FeaturedNOTICIAS

¿Qué viene con React 18? – CloudSavvy TI


Reaccionar logotipo sobre un fondo oscuro

React 18 será el próximo lanzamiento importante de la popular biblioteca de componentes de JavaScript. Ahora disponible como versión candidata, presenta varios cambios para mejorar la recuperación de datos, el rendimiento y la representación del lado del servidor.

Para aprovechar todas las funciones, deberá actualizar su proyecto y es posible que experimente algunos cambios sustanciales. Sin embargo, React 18 sigue siendo generalmente compatible con códigos anteriores. Deberías poder pasar la versión de lanzamiento a la tuya package.json sin enfrentar demasiados problemas inmediatos.

Renderizado simultáneo

La razón detrás de la mayoría de las revisiones de React 18 tiene que ver con algo llamado «representación concurrente». Este mecanismo le da a React una forma de ensamblar múltiples versiones del árbol de componentes al mismo tiempo. Si bien los detalles de esto solo son relevantes para las funciones internas de la biblioteca, el resultado es una mayor flexibilidad y un rendimiento mejorado para su aplicación.

El renderizado simultáneo hace que el proceso de renderizado se interrumpa. Si bien un renderizado en React 17 debe completarse una vez que comienza, React 18 proporciona una forma de detenerse a la mitad y retomarlo más tarde.

Esta capacidad significa que es menos probable que los renderizados de React afecten el rendimiento general del navegador. Hasta ahora, los eventos del navegador, como presionar teclas y pintar, están bloqueados mientras se realiza un procesamiento. Con el renderizado simultáneo habilitado, presionar una tecla detendrá el renderizado, permitirá que el navegador maneje el cambio y luego reanude el renderizado.

Esto da como resultado una experiencia de usuario más fluida que es menos susceptible de tartamudear cuando el renderizado coincide con otras actividades. React mantiene múltiples ramas de trabajo; una vez que se representa una rama, lo que puede ocurrir en varias sesiones distintas, se acepta en la rama principal que produce la interfaz de usuario visible.

Modo simultáneo vs renderizado simultáneo

Antes de que React 18 alcanzara el estado alfa, esta característica se llamaba «modo simultáneo». Es posible que aún vea este nombre en artículos y documentación anteriores. El concepto de renderizado simultáneo como un modo separado ya no existe en React 18. Esto facilita que las aplicaciones existentes cambien al nuevo enfoque.

El renderizado simultáneo es fundamentalmente diferente del sistema de renderizado existente. Tiene una API completamente nueva que reemplaza a la familiar. ReactDOM.render(). En los días del modo concurrente, la competencia era todo o nada: estaba habilitada para su aplicación, con la perspectiva de cambios sustanciales o completamente fuera de los límites. Ahora se maneja de manera más elegante con React que solo aplica renderizado concurrente a las actualizaciones de DOM que realmente requieren funcionalidad concurrente.

La nueva API raíz (habilitando el modo concurrente)

Las aplicaciones existentes actualizadas a React 18 pueden seguir utilizándose ReactDOM.render() en el futuro inmediato. Esto renderizará su aplicación sin el soporte de la competencia, utilizando el conocido renderizador de v17. Verá una advertencia en la consola de que la API ya no es compatible, pero esto puede ignorarse al actualizar.

import App from "./App.js";
import ReactDOM from "react-dom";
 
// "ReactDOM.render is no longer supported in React 18"
ReactDOM.render(<App />, document.getElementById("root"));

Para eliminar la advertencia, cambie a la nueva createRoot() API:

import {createRoot} from "react-dom/client";
const root = createRoot(document.getElementById("root"));
root.render(<App />);

createRoot() devuelve un nuevo objeto raíz que representa una superficie de renderizado de React. puedes llamarlo render() método para renderizar un componente React en la raíz. El resultado del código anterior es el mismo que el anterior. ReactDOM.render() ejemplo. createRoot() es una interfaz más orientada a objetos con mayor facilidad de uso.

Raíces producidas por createRoot() admite renderizado simultáneo. Actualizar a esta API le da acceso a nuevas funciones en React 18.

los createRoot() equivalente a ReactDOM.unmountComponentAtNode() Es el nuevo unmount() método expuesto en los objetos raíz. Puede usarlo para separar el árbol de componentes de React y dejar de renderizar su aplicación:

import App from "./App.js";
import ReactDOM from "react-dom";
 
// OLD
ReactDOM.unmountComponentAtNode(document.getElementById("root"));
 
// NEW
const root = createRoot(document.getElementById("root"));
root.unmount();

Funcionalidad simultánea

La representación simultánea le permite utilizar funciones simultáneas para mejorar el rendimiento de su aplicación. Estas son algunas de las API clave disponibles.

Suspenso

los <Suspense> El componente ha existido desde React 16. Le permite evitar la representación de los elementos secundarios de un componente hasta que se cumpla una condición. Se usa comúnmente para la recuperación de datos y la importación de módulos asíncronos.

const fetchPostHistory = id => fetch(`/users/${id}/posts`);
 
const UserCard = ({Id, Name}) => {
 
    const [postHistory] = useState(() => fetchPostHistory(Id));
 
    <div>
        <h1>{Name}</h1>
        <React.Suspense fallback="Loading...">
            <UserPostHistoryList posts={postHistory} />
            <ReportUserLink id={Id} />
        </React.Suspense>
    </div>
};

En este ejemplo, ni el UserPostHistory o ReportUserLink los componentes aparecerán hasta que los datos del historial de publicaciones del usuario se hayan recuperado de la red. Ya funciona bien en muchas situaciones, pero la implementación de React 17 tiene algunas peculiaridades.

Si registrara los efectos de cada componente, vería el ReportUserLink el componente se representó mientras las publicaciones aún se estaban cargando, aunque no es visible en ese momento. Usando la explicación de concurrencia anterior, puede explicar por qué: una vez que React comenzó a representar el árbol de componentes, no tuvo oportunidad de detenerse, a pesar de que un humano puede detectarlo. ReportUserLink es redundante hasta postHistory está poblada.

El suspenso es más poderoso en React 18. La nueva versión se llama «Concurrent Suspense»; la implementación anterior ahora se llama Legacy Suspense. Soluciona el problema en el ejemplo anterior: renderizar el mismo código con la concurrencia habilitada evitará que el renderizador alcance <ReportUserLink> mientras la recuperación de datos está en progreso.

Registrar los efectos de cada componente demostraría esto ReportUserLink solo se activa cuando el historial de publicaciones está disponible. React deja de renderizar cuando alcanza UserPostHistoryList y debe esperar a que se carguen los datos. Una vez que se completa la llamada de red, React continúa representando el resto del subárbol de Suspense.

Esta característica ayuda a evitar una pérdida de trabajo que sus usuarios nunca aprovechan. También aborda varios problemas con Suspense donde los componentes pueden haber realizado efectos antes de lo esperado. Finalmente, esta solución proporciona una garantía automática de que los datos llegan en el orden requerido. No tiene que preocuparse por las condiciones de carrera, ya que la representación se interrumpe durante la recuperación de datos.

Transiciones

Las transiciones son una nueva función habilitada para la simultaneidad. Esta API es una forma de informar a React sobre las prioridades relativas de las actualizaciones de la interfaz de usuario. Una «transición» es una actualización de prioridad relativamente baja, como cambiar entre pantallas principales. Las actualizaciones, como volver a renderizar en respuesta a la entrada del teclado y otras interacciones del usuario, se consideran más urgentes.

Marcar una actualización como una transición tiene algunos efectos sobre cómo React se acerca a su finalización. React utilizará las capacidades de renderizado interrumpible de la competencia para pausar la actualización si llega una más urgente a mitad de camino. Esto ayudará a que su interfaz de usuario responda a la entrada del usuario mientras el renderizado está en progreso, reduciendo la tartamudez y el bloqueo.

Las transiciones son útiles en una amplia variedad de situaciones: la actualización de un panel de notificación en el encabezado de la aplicación, la administración de actualizaciones en la barra lateral y el cambio de otros auxiliares de la interfaz de usuario son buenos candidatos. También funcionan bien para acciones asincrónicas realizadas en respuesta a la entrada del usuario, como el caso clásico de una barra de búsqueda que se actualiza a medida que el usuario escribe.

Esto puede ser difícil de arreglar en React: sin una solución cuidadosa, es común sentir un retraso notable ya que las actualizaciones causadas por la obtención de nuevos resultados bloquean temporalmente el hilo principal para que no maneje la entrada del teclado. Con React 18, puede usar una transición para marcar esas actualizaciones como trabajos de baja prioridad.

los startTransition() La API encapsula las actualizaciones de estado como transiciones:

import {startTransition} from "react";
 
const Component = () => {
 
    const [searchQuery, setSearchQuery] = useState("");
    const [searchResults, setSearchResults] = useState({});
 
    /**
     * State updates within the transition function are low-priority
     */
    startTransition(() => {
        setSearchResults({text: "Search Result 1"});
    });
 
};

Si desea verificar si hay una actualización en curso, simplemente reemplace startTransition() con el useTransition() gancho. Esto le da un valor booleano que indica si una transición tiene algún trabajo pendiente.

import {useTransition} from "react";
 
const Component = () => {
 
    const [searchQuery, setSearchQuery] = useState("");
    const [searchResults, setSearchResults] = useState({});
 
    const [isSearching, startSearchResultsTransition] = useTransition();
 
    startSearchResultsTransition(() => {
        setSearchResults({text: "Search Result 1"});
    });
 
    return (
        <div>
            <input onChange={setSearchQuery} value={searchQuery} />
            <SearchResults results={searchResults} />
            {(isSearching && "(Searching...)")}
        </div>
    );
 
};

Todas las actualizaciones de estado existentes se tratan como actualizaciones periódicas urgentes para mantener la compatibilidad con versiones anteriores del código anterior.

Valores diferidos

Los valores diferidos son otra forma de mantener la capacidad de respuesta durante las actualizaciones de larga duración. Cuando un valor es diferente del useDeferredValue() gancho, React seguirá mostrándolo viejo valor para un período determinado.

const Component = () => {
    const [results, setResults] = useState([]);
    const deferredResults = useDeferredResults(results, {timeoutMs: 5000});
    return <ResultsGrid results={deferredResults} />;
};

Permitir que React continúe mostrando resultados antiguos durante cinco segundos evita ralentizaciones al eliminar la necesidad de procesar inmediatamente los datos recuperados a medida que llegan. Es una forma de rebote integrada en la gestión de estado de React. Los datos pueden retrasarse unos segundos con respecto a su estado real para reducir la cantidad total de trabajo realizado.

Mejor dosificación

Un último cambio orientado al rendimiento en React 18 es una serie de mejoras en el lote de actualizaciones de estado. React ya intenta combinar actualizaciones de estado en varias situaciones simples:

const Component = () => {
 
    const [query, setQuery] = useState("");
    const [queryCount, setQueryCount] = useState("");
 
    /**
     * Two state updates, only one re-render
     */
    setQuery("demo");
    setQueryCount(queryCount + 1);
 
};

Sin embargo, hay varias situaciones en las que esto no funciona. A partir de React 18, se aplica el procesamiento por lotes todo el mundo actualizaciones, independientemente de su procedencia. Las actualizaciones que provienen de los tiempos de espera del navegador, las promesas y los controladores de eventos se agruparán completamente en lotes de la misma manera que el código que se encuentra directamente dentro del componente.

Este cambio podría alterar el comportamiento de algunos códigos. Si tiene un componente antiguo que actualiza el estado varias veces en los lugares enumerados anteriormente, verifique los valores a la mitad, es posible que no sean lo que espera en React 18. flushSync está disponible para forzar manualmente la confirmación de una actualización de estado, lo que le permite desactivar el lote.

const Component = () => {
 
    const [query, setQuery] = useState("");
    const [queryCount, setQueryCount] = useState("");
 
    const handleSearch = query => {
       fetch(query).then(() => {
 
            /**
             * Force commit and update the DOM
             */
            flushSync(() => setQuery(query));
 
            setQueryCount(1);
 
        });
    }
 
};

Cambios en la representación del lado del servidor

La representación del lado del servidor se ha revisado en gran medida. La nueva característica principal es la compatibilidad con la transmisión de renderizado, donde se puede transmitir HTML nuevo desde el servidor a su cliente React. Esto le permite usar los componentes de Suspense en el lado del servidor.

Como resultado de este cambio, varias API han quedado en desuso o se han reelaborado, incluidas renderToNodeStream(). Ahora deberías usar renderToPipeableStream() o renderToReadableStream() para proporcionar contenido del lado del servidor compatible con los entornos de transmisión modernos.

La hidratación del lado del cliente del contenido renderizado por el servidor también ha cambiado para alinearse con la nueva API de renderizado concurrente. Si está utilizando la representación del servidor y el modo concurrente, reemplace hydrate() con hydrateRoot():

// OLD
import {hydrate} from "react-dom";
hydrate(<App />, document.getElementById("root"));
 
// NEW
import {hydrateRoot} from "react-dom/client";
hydrateRoot(document.getElementById("root"), <App />);

Los efectos del renderizado de transmisión hacen que el renderizado del servidor sea más adecuado para varios casos de uso. La implementación existente del lado del servidor de React requiere que el cliente recupere e hidrate toda la aplicación antes de que se vuelva interactiva. Al agregar flujos y suspenso, React puede recuperar solo los bits necesarios para la representación inicial y luego cargar datos adicionales no esenciales del servidor después de que la aplicación se vuelve interactiva.

Conclusión

React 18 trae nuevas funciones y mejoras de rendimiento para sus aplicaciones. Funciones como Suspenso y Transiciones hacen que los diferentes tipos de código sean más fáciles de escribir y menos impactantes en otras áreas de la aplicación.

Actualizar a React 18 cuando se lanza debería ser bastante sencillo en la mayoría de los casos. Puede continuar usando la API raíz de React 17 por el momento antes de pasar a createRoot() cuando esté listo para adoptar el renderizado simultáneo. Si desea comenzar a preparar su aplicación hoy, puede instalar la última versión candidata ejecutando npm install [email protected] [email protected].

TE INTERESA>>  “Vamos a creer hasta el final”

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

Botón volver arriba