Cómo actualizar a React 18
React 18 evoluciona el popular marco de componentes de JavaScript con nuevas funciones creadas en torno a la representación y el suspenso simultáneos. Promete un mejor rendimiento, más capacidades y una experiencia de desarrollador mejorada para las aplicaciones que hacen el cambio.
En este artículo, le mostraremos cómo actualizar sus bases de código existentes a React 18. Tenga en cuenta que esta guía es solo una descripción general de los cambios más aplicables. La migración debería ser bastante sencilla para proyectos pequeños que ya siguen las mejores prácticas de React; grandes conjuntos de componentes complejos pueden generar algunos problemas, que detallaremos a continuación.
Instalación de Reaccionar 18
Antes de hacer cualquier otra cosa, use npm para actualizar la dependencia React de su proyecto a v18:
$ npm install [email protected] [email protected]
La nueva versión técnicamente no tiene ninguna incompatibilidad con versiones anteriores. Las nuevas funciones se activan de forma voluntaria. Como aún no ha cambiado ningún código, debería poder iniciar su aplicación y observar cómo se procesa correctamente. Su proyecto se ejecutará con su comportamiento React 17 existente.
$ npm start
Habilitación de las funciones de React 18: la nueva API raíz
El uso de React 18 sin ningún cambio en la base de código causará un efecto secundario: verá una advertencia en la consola del navegador cada vez que su aplicación se monte en modo de desarrollo.
ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17.
Este mensaje de obsolescencia se puede ignorar de forma segura si no está listo para actualizar su proyecto. Cuando desee adoptar las capacidades de React 18, debe realizar el cambio que describe. El viejo ReactDOM.render()
La función ha sido reemplazada con una nueva API raíz que está más orientada a objetos. Además de mejorar la facilidad de uso, también activa el sistema de renderizado simultáneo que impulsa todas las nuevas funciones de titulares.
dentro de tu index.js
o app.js
archivo, busque las líneas que son similares a estas:
import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(<App />, container);
Este es un punto de entrada típico para una aplicación React. Representa una instancia de lo importado. App
componente como elemento raíz de su aplicación. El contenido renderizado se deposita como el innerHTML
del elemento HTML con id="react"
.
Para cambiar a la API raíz de React 18, reemplace el código anterior con lo siguiente:
import App from "./App.js"; import {createRoot} from "react-dom/client"; const container = document.getElementById("react"); const root = createRoot(container); root.render(<App />);
Esto tiene un efecto equivalente al antiguo ReactDOM.render()
API. En lugar de inicializar un elemento raíz y renderizar su aplicación como una única operación imperativa, React 18 le hace crear primero un objeto raíz y luego renderizar explícitamente su contenido.
A continuación, busque cualquier lugar en su código donde desmonte su nodo raíz. Cambio ReactDOM.unmountComponentAtNode()
a lo nuevo unmount()
método en su objeto raíz:
// Before import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(<App />, container); ReactDOM.unmountComponentAtNode(container); // After import App from "./App.js"; import {createRoot} from "react-dom/client"; const container = document.getElementById("react"); const root = createRoot(container); root.render(<App />); root.unmount();
Sustitución de devoluciones de llamadas de procesamiento
los ReactDOM.render()
El argumento de devolución de llamada opcional del método no tiene una contraparte directa en la API raíz de React 18. Anteriormente podía usar este código para iniciar sesión Rendered!
a la consola después de que React haya terminado de renderizar el nodo raíz:
import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.render(<App />, container, () => console.log("Rendered!"));
Esta funcionalidad se eliminó porque el momento de la invocación de la devolución de llamada es impredecible cuando se usan las nuevas funciones de hidratación parcial y renderizado del servidor de transmisión de React 18. Si ya está utilizando devoluciones de llamada de procesamiento y necesita mantener la compatibilidad, puede lograr un comportamiento similar utilizando el mecanismo de refs:
import {createRoot} from "react-dom/client"; const App = ({callback}) => ( <div ref={callback}> <h1>Demo App</h1> </div> ); const container = document.getElementById("react"); const root = createRoot(container); root.render(<App callback={() => console.log("Rendered!")} />);
React llama a las referencias de función cuando se montan los componentes. Establecer una referencia en el componente que es su nodo raíz le permite detectar cuándo se produce el procesamiento, proporcionando un efecto similar al antiguo sistema de devolución de llamada de procesamiento.
Depuración de problemas de actualización
Su aplicación ahora debería estar procesando usando las características de React 18 y sin ninguna advertencia de consola. Pruebe su aplicación a fondo para asegurarse de que todo sigue funcionando como espera. Si encuentra problemas, es posible que pueda resolverlos con estas resoluciones comunes.
Buscar
Aplicaciones envueltas en el <StrictMode>
El componente puede comportarse de manera diferente cuando se renderiza en el modo de desarrollo de React 18. Esto se debe a que el modo estricto ahora prueba si su base de código admite el estado reutilizable, un concepto que se introducirá por completo en React en una versión futura.
El estado reutilizable permite que React vuelva a montar un componente previamente eliminado con su último estado restaurado automáticamente. Esto requiere que sus componentes sean resistentes a la doble invocación de efectos. El modo estricto ahora lo ayuda a prepararse para el estado reutilizable al simular el montaje, desmontaje y montaje de sus componentes cada vez que se usan, lo que revela cualquier problema en el que no se pueda restaurar el estado anterior. Puede deshabilitar el Modo estricto si encuentra problemas en su aplicación o sus dependencias que no está listo para abordar.
Admite lotes de actualización de estado
React 18 cambia la forma en que se "agrupan" las actualizaciones de estado para mejorar el rendimiento. Cuando cambia los valores de estado varias veces en una función, React intenta combinarlos en una sola representación:
const Component = () => { const [query, setQuery] = useState(""); const [queryCount, setQueryCount] = useState(0); /** * Two state updates, only one re-render */ setQuery("demo"); setQueryCount(queryCount + 1); };
Este mecanismo aumenta la eficiencia, pero anteriormente solo funcionaba dentro de los controladores de eventos de React. Con React 18, funciona con todas las actualizaciones de estado, incluso si se originan en controladores de eventos nativos, tiempos de espera o promesas. Es posible que algún código se comporte de manera diferente a antes si realiza actualizaciones de estado consecutivas en cualquiera de estos lugares.
const Component = () => { const [query, setQuery] = useState(""); const [queryId, setQueryId] = useState(""); const [queryCount, setQueryCount] = useState(0); const handleSearch = query => { fetch(query).then(() => { setQuery("demo"); setQueryCount(1); // In React 17, sets to "query-1" // In React 18, sets to "query-0" - previous state update is batched with this one setQueryId(`query-${queryCount}`); }); } };
Puede deshabilitar este comportamiento en situaciones en las que no esté listo para refactorizar su código. Envuelva las actualizaciones de estado en flushSync()
obligarlos a cometer inmediatamente:
const Component = () => { const [query, setQuery] = useState(""); const [queryId, setQueryId] = useState(""); const [queryCount, setQueryCount] = useState(0); const handleSearch = query => { fetch(query).then(() => { flushSync(() => { setQuery("demo"); setQueryCount(1); }); // Sets to "query-1" setQueryId(`query-${queryCount}`); }); } };
Deje de usar funciones eliminadas y no admitidas
Una vez que se hayan abordado todos los aspectos anteriores, su aplicación debería ser totalmente compatible con React 18. Aunque hay algunos cambios más en la superficie de la API, estos no deberían afectar a la mayoría de las aplicaciones. Aquí hay algunos a tener en cuenta:
unstable_changedBits
ha sido removido - Esta API no compatible permitía optar por no recibir actualizaciones de contexto. Ya no está disponible.- los
Object.assign()
Se ha eliminado el relleno polivinílico. - Debe agregar manualmente elobject-assign
paquete polyfill si necesita admitir navegadores muy antiguos sin unObject.assign()
. - Internet Explorer ya no es compatible - React ha eliminado oficialmente la compatibilidad con Internet Explorer antes del final del soporte del navegador en junio. No debe actualizar a React 18 si aún necesita que su aplicación se ejecute en IE.
- Usar el suspenso con un
undefined
respaldo ahora es equivalente anull
- Límites de suspenso confallback={undefined}
se omitieron anteriormente, lo que permite que el código se transmita en cascada al siguiente límite principal en el árbol. React 18 ahora respeta los componentes de suspenso sin respaldo.
Representación del lado del servidor
Las aplicaciones que utilizan la representación del lado del servidor requerirán algunos cambios más para funcionar con React 18.
En línea con la nueva API raíz, debe reemplazar la antigua hydrate()
función en su código del lado del cliente con el nuevo hydrateRoot()
proporcionado por el react-dom/client
paquete:
// Before import App from "./App.js"; import ReactDOM from "react-dom"; const container = document.getElementById("react"); ReactDOM.hydrate(<App />, container); // After import App from "./App.js"; import {createRoot} from "react-dom/client"; const container = document.getElementById("react"); const root = hydrateRoot(container, <App />);
En el código del lado del servidor, reemplace las llamadas a la API de representación en desuso con sus nuevas contrapartes. En la mayoría de los casos, debe cambiar renderToNodeStream()
a lo nuevo renderToReadableStream()
. Las nuevas API de transmisión desbloquean el acceso a las capacidades de procesamiento del servidor de transmisión de React 18, donde el servidor puede seguir entregando HTML nuevo al navegador después del procesamiento inicial de su aplicación.
Comience a usar las características de React 18
Ahora que ha actualizado, puede comenzar a hacer que su aplicación sea más poderosa al incorporar las funciones de React 18. El uso de React de la concurrencia significa que los renderizados de componentes pueden interrumpirse, desbloqueando nuevas capacidades y IU más receptivas.
Algunas de las características añadidas incluyen actualizaciones importantes de Suspense, una forma de designar la prioridad de las actualizaciones de estado con Transiciones y un mecanismo integrado para acelerar las re-renderizaciones causadas por actualizaciones no urgentes pero de alta frecuencia. También hay varios cambios y mejoras misceláneas: puede volver undefined
de un componente render()
método, la advertencia sobre llamar setState()
en componentes desmontados se ha eliminado, y varios atributos HTML nuevos como imageSizes
, imageSrcSet
y aria-description
son reconocidos por el renderizador de React DOM.
Resumen
React 18 es estable y está listo para usar. En la mayoría de los casos, el proceso de actualización debe ser rápido y fácil, y solo requiere una actualización de npm y un cambio a la nueva API raíz. Sin embargo, aún debe probar todos sus componentes: pueden comportarse de manera diferente en algunas situaciones, como en modo estricto o cuando se aplica el procesamiento por lotes automático.
Esta nueva versión apunta a la dirección futura de React como un marco de trabajo de alto rendimiento para todo tipo de aplicaciones web. También amplía las capacidades de renderizado del lado del servidor de React, agregando Suspense en el servidor y la capacidad de seguir transmitiendo contenido a sus usuarios después del renderizado inicial. Esto brinda a los desarrolladores más flexibilidad para distribuir el renderizado tanto en el cliente como en el servidor.
Descubre más contenido