React 17.0 — La novedad es que no hay novedades
Descubre el nuevo cambio de versión de ReactJS y por qué de momento no hay novedades
Hace unos días el equipo de ReactJS anunciaba la publicación de la primera release candidate de la versión 17 de React en su blog oficial:
https://reactjs.org/blog/2020/08/10/react-v17-rc.htm
Lo más llamativo de este anuncio es que esta actualización no incluirá nuevas características aunque sí supone un cambio muy importante (y por lo que comentan necesario) para la evolución y mantenimiento de la propia librería. ¡Vamos a ver por qué!
Actualizaciones graduales
Las actualizaciones que ha ido introduciendo React en los últimos tiempos han supuesto a menudo la introducción de “deprecaciones” de funcionalidades antiguas, lo cual provocaba que los equipos de desarrollo tuvieran a menudo problemas para introducir estas nuevas actualizaciones, especialmente en aplicaciones grandes.
Es por ello que el objetivo de esta primera versión de React 17 sea introducir un método que permita introducir estas actualizaciones de forma menos “dolorosa”. A partir de ahora cuando React se actualice habrá opciones que nos permitirán actualizar nuestra aplicación parte por parte a esta nueva versión en vez de hacerlo todo de golpe. Por ejemplo, podremos decidir mantener una determinada parte del código en una versión anterior mientras que el resto queda actualizada a la nueva versión.
Dado que las actualizaciones graduales suponen tener ejecutándose varias versiones de ReactJS, todo el sistema de gestión de eventos que implementa React por debajo ha tenido que ser rescrito.
🤓 ¡Ojo! Tal y como apunta el equipo de React, realizar la actualización de golpe todavía sigue siendo la mejor opción, ya que esta forma de introducir actualizaciones graduales supone tener corriendo dos versiones distintas de React, lo cual no es lo ideal.
Cambios en el sistema de eventos
Aunque hasta ahora no era imposible tener varias versiones de React ejecutándose en nuestra aplicación, esto solía provocar numerosos dolores de cabeza por la forma en que React gestiona los eventos. Por ejemplo, el editor de código Atom encontró un problema relacionado con esto hace casi 4 años:
Este problema está relacionado con la forma que React asocia los eventos. Cuando escribimos esto:
<button onClick={handleClick}>
React no traduce ese código a esto:
someButton.addEventListener('click', handleClick);
Sino que adjunta ese evento directamente al nodo document
del DOM (lo que se conoce como event delegation y que permite optimizar el rendimiento con árboles muy grandes así como volver a ejecutar eventos). Por tanto, cuando un evento tiene lugar en el DOM, React busca el componente al que tiene que llamar y deja que se propague hacia arriba (bubbles up) a través del árbol de componentes.
Sin embargo, y aquí viene el problema, en Javascript nativo este evento ya se habrá propagado también el nivel del elemento document
, lo cual y como indicaba anteriormente, provoca situaciones extrañas cuando por ejemplo mezclamos React con otras librerías como jQuery o tenemos varias versiones de React ejecutándose: aunque el árbol interno invoque event.stopPropagation
, el árbol que envuelva a dicho árbol todavía recibirá el evento. Dicho de otro modo, si tenemos una aplicación escrita en jQuery y dentro un trozo que funciona con React, invocar event.stopPropagation
en React no impedirá que el evento llegue a jQuery.
Por tanto, a partir de la versión 17 de React, los event handlers serán añadidos al elemento raíz del DOM que contiene la aplicación donde React es renderizado. Es decir, el elemento al que hacemos referencia aquí:
const rootNode = document.getElementById('root');
ReactDOM.render(<App />, rootNode);// React < 17
document.addEventListener()// React >= 17
rootNode.addEventListener()
Gracias a este cambio resultará mucho más fácil embeber una versión de ReactJS dentro de otra, siempre y cuando ambas versiones sean como mínimo la 17. Por eso es tan importante este cambio.
Cambios en useEffect
Otro cambio muy importante de esta nueva versión de React es el momento en que se produce la limpia de los efectos declarados mediante el hook useEffect
:
useEffect(() => {
// The effect
return () => {
// Its cleanup.
};
});
En la versión 16 de React, la limpieza del efecto se producía de forma síncrona (del mismo modo que sucedía con el método componentWillUnmount
de los componentes basados en clase) lo cual provocaba algunos problemas de rendimiento.
A partir de la versión 17 de React, la limpieza de los efectos se ejecuta de forma asíncrona de modo que si por ejemplo nuestro componente se desmonta, la limpieza del efecto se ejecutará después de que la pantalla se haya actualizado.
Este cambio sólo afecta al hook useEffect
ya que useLayoutEffect
mantendrá su ejecución síncrona.
Otros cambios
Si bien los dos cambios anteriores son para mí los más importantes, React 17 introduce otra serie de cambios que quiero mencionar al menos de pasada por si afectan a vuestras aplicaciones:
- La optimización del pool de eventos que realizaba React es eliminada debido a que ya no introduce mejoras de rendimiento en navegadores modernos de modo que ahora es seguro los campos de los eventos cuando los necesitemos.
- A partir de ahora si empleamos las funciones
forwardRef
omemo
y el componente devuelveundefined
, React tratará esto como un error. - Y finalmente la generación del stack de componentes ha sido modificada de modo que ahora es más sencillo saber qué componente produjo el error.
¿Quieres probar React 17?
Si te ha picado la curiosidad y quieres comenzar a probar esta nueva versión de React puedes hacerlo instalándola mediante yarn:
yarn add react@17.0.0-rc.0 react-dom@17.0.0-rc.0
Conclusiones
Como veis, esta versión 17 de ReactJS no introduce ninguna novedad en lo que a características se refiere. Sin embargo, estoy seguro de que se han puesto los cimientos para que cuando comiencen a liberarse nuevas versiones tengamos sorpresas más que interesantes que os iré comentando por aquí.
¿Quieres recibir más artículos como este?
Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇