El uso de bibliotecas de terceros es muy común al desarrollar aplicaciones para la web. La forma habitual es instalar el paquete NPM de la biblioteca e importarlo para su uso.
Pero a veces, el paquete NPM no está disponible o debe incluir archivos directamente desde un CDN o una fuente externa. Agregar etiquetas <script>
en el archivo index.html no siempre funciona, e incluso si lo hace, podría causar problemas a medida que el sitio web escala.
Enfrenté un problema similar al agregar la importación de Calendly a mi sitio de cartera y encontré una solución fácil. Pero primero, entendamos por qué ocurre exactamente un error cuando agrega etiquetas <script>
en los componentes de React.
React usa React DOM para representar contenido JSX en la página web. React DOM es un DOM virtual que reside sobre el DOM original. Solo actualiza los nodos modificados del DOM, a diferencia del DOM original, que se actualiza por completo después de cada cambio. React DOM usa createElement
para convertir JSX en elementos DOM.
La función createElement
usa la API innerHTML
para agregar nodos modificados en el DOM original del navegador. Las especificaciones de HTML5 establecen que las etiquetas <script>
no se ejecutan si se insertan con innerHTML
. MDN Web Docs ha explicado las razones de seguridad detrás de esto.
Como resultado, la ejecución de la etiqueta <script>
genera un error en React.
La solución más simple es agregar secuencias de comandos directamente en DOM utilizando la interfaz de Document
proporcionada por las API web. Podemos usar los métodos de manipulación DOM de JavaScript para inyectar la etiqueta <script>
sin que React DOM interfiera.
Esto es lo que tenemos que hacer:
En términos de React, el script deseado debe agregarse a DOM cuando el componente se carga en el navegador. React tiene un gancho para tales escenarios: useEffect
. Todo el proceso explicado anteriormente se puede envolver dentro del enlace y activarse cuando el componente se procesa por primera vez o se agrega un nuevo script.
En proyectos del mundo real, es posible que deseemos agregar varios scripts. Por lo tanto, es mejor crear un enlace personalizado, para que podamos llamarlo varias veces con diferentes enlaces de origen.
Los ganchos personalizados generalmente se almacenan en un directorio separado dentro de la carpeta /src
. Vamos a crear un nuevo archivo dentro del directorio /src/hooks/
y asígnele el nombre useExternalScripts.js
. Pegue el siguiente código en el archivo:
import { useEffect } from 'react'; export default function useExternalScripts({ url }){ useEffect(() => { const head = document.querySelector("head"); const script = document.createElement("script"); script.setAttribute("src", url); head.appendChild(script); return () => { head.removeChild(script); }; }, [url]); };
En un componente en el que desee agregar un nuevo script, pegue el siguiente código:
import useExternalScripts from "./hooks/useExternalScripts" const Component = () => { useExternalScripts("https://www.scriptdomain.com/script") ... }
Se agrega un nuevo script al encabezado de la página cada vez que el componente se monta en el DOM. El script se elimina cuando se desmonta el componente.
No use el fragmento de código de return
si su secuencia de comandos se usa en varios componentes a lo largo de su aplicación. La función devuelta por el gancho es una función de limpieza, que se ejecuta cuando se desmonta un componente. Por lo tanto, no lo requerimos si tenemos que usar la fuente en varios lugares.
Alternativamente, puede usar react-helmet , que administra los cambios dentro de la etiqueta <head>
. El <Helmet>
puede encargarse del script si se coloca dentro de él.
import { Helmet } from "react-helmet" export default function Component() { return ( <> <Helmet> <script src="https://www.myscripts.com/scripts" crossorigin="anonymous" async ></script> </Helmet> ... </> ) }
¡No olvides instalar react-helmet antes de iniciar tu aplicación!
React usa innerHTML
en el núcleo para manipular nodos en el DOM del navegador. La API de innerHTML
no admite etiquetas <script>
por motivos de seguridad. Por lo tanto, se genera un error si intenta inyectar una etiqueta <script>
en un componente React.
Agregar una nueva etiqueta de script y agregarla directamente al elemento <head>
de la página es la forma más fácil de agregar etiquetas <script>
en la aplicación React. react-helmet es una biblioteca de terceros que se puede usar para lograr lo mismo manejando la etiqueta <head>
en cada página.
Siento que la versión de enlace personalizada es mejor que usar una biblioteca de terceros, ya que tenemos control total sobre ella. ¿Qué piensas? ¿Usaste algún otro método? ¡Házmelo saber abajo!
Si encuentra útil este blog, considere compartirlo en sus redes sociales. Puede leer más blogs sobre desarrollo web, código abierto y cosas que soluciono mientras desarrollo aplicaciones en mi blog . O si quieres saludarme, soy de lo más activo en Twitter .
Hasta entonces, ¡feliz depuración! ⛑
También publicado aquí