En React 18 se introdujeron una serie de cambios y optimizaciones dedicadas a mejorar el rendimiento de los componentes funcionales y colocarlos como la opción predeterminada a la hora de desarrollar componentes React. Si has utilizado una versión de React posterior a la 18, sin embargo, puede que hayas notado un comportamiento particular que puede sorprender a primeras, pero que verás que tiene mucho sentido.
Durante el proceso de desarrollo, lo más habitual es tener el modo de desarrollo de React activo para disponer de mensajes de error útiles cuando cometemos algún fallo. También se recomienda no desactivar el StrictMode
, que ya viene activo por defecto cuando creamos un nuevo proyecto con Vite:
// main.jsx
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
En estas condiciones, podrás observar que al renderizar un componente React, algunas sentencias se ejecutan dos veces.
Si quieres comprobarlo, simplemente añade un console.log("Hola!")
a cualquier componente funcional. Como resultado, verás que en la consola de tu navegador aparece el mensaje dos veces. Si no tienes instaladas las herramientas de desarrollo de React para tu navegador, puede que se colapsen los mensajes pero aparezca un número "2" indicando que el mensaje se ha duplicado:
Por otro lado, si has instalado previamente las herramientas de desarrollo de React, estas provocarán el desglose del mensaje duplicado, haciendo que se vea dos veces en la consola, aunque la segunda se vea menos resaltada:
Este comportamiento, aunque sorprendente, es intencionado en el modo de desarrollo de React, y nos permite detectar comportamientos "impuros" en los componentes, que son aquellos que pueden tener efectos externos como modificar directamente variables externas, llamar a una API, etc. Todos estos efectos secundarios son no deseados puesto que lo ideal es que cada componente React sea una función totalmente predecible: si tiene el mismo estado y recibe las mismas propiedades, su resultado debería ser siempre el mismo.
Sin embargo, es muy fácil tener un desliz y colocar alguna llamada que no deberíamos en el cuerpo del componente. Si esto ocurre, será más fácil detectarlo con el nuevo modo de desarrollo de React, ya que nos daremos cuenta de que alguna operación se está ejecutando por duplicado.
Recuerda que para realizar operaciones con este tipo de efectos secundarios debemos utilizar la función useEffect
, que nos permite "limpiar" o deshacer efectos que no deban permanecer antes de volver a renderizar el componente.
useEffect(() => {
// Efecto:
const feed = getFeed(idFeed);
feed.suscribirse();
// Limpieza del efecto:
return () => {
feed.desuscribirse();
};
}, [idFeed]);
Durante el desarrollo, React realizará un ciclo completo de montaje-limpieza del componente y lo volverá a montar, provocando que el efecto se ejecute, se deshaga y se vuelva a ejecutar de seguido. Así, si la lógica de limpieza no está implementada o es incorrecta, también podremos detectarlo.
Puedes leer más información sobre las razones por las que React se comporta de esta forma en la documentación de React.