Aventuras de Renderizado Concurrente en React 18

Rate this content
Bookmark

Con el lanzamiento de React 18 finalmente obtenemos el esperado renderizado concurrente. Pero, ¿cómo afectará esto a tu aplicación? ¿Cuáles son los beneficios del renderizado concurrente en React? ¿Qué necesitas hacer para cambiar al renderizado concurrente al actualizar a React 18? ¿Y qué pasa si no quieres o no puedes usar el renderizado concurrente aún?

¡Hay algunos cambios de comportamiento de los que debes estar al tanto! En este masterclass cubriremos todos esos temas y más.

Únete a mí con tu laptop en este masterclass interactivo. Verás lo fácil que es cambiar al renderizado concurrente en tu aplicación de React. Aprenderás todo sobre el renderizado concurrente, SuspenseList, la API startTransition y más.

132 min
27 Oct, 2021

Comments

Sign in or register to post your comment.
  • Narges Haeri
    Narges Haeri
    Aspiring Professional
    Thank you so much for such great content. Your workshop was incredibly helpful!

Video Summary and Transcription

El masterclass cubre las nuevas características de React 17 y React 18, incluyendo suspense, manejo de errores y modo concurrente. Enfatiza la importancia del aprendizaje práctico y escribir código en lugar de simplemente copiar. El masterclass explora el uso de suspense y límites de errores para manejar errores y mejorar la experiencia del usuario. También introduce nuevas características en React 18, como start transition y useTransition, para mejorar la capacidad de respuesta. Se discute la interacción entre suspense y start transition, resaltando su colaboración en el manejo de la interfaz de usuario de respaldo y la comunicación.

Available in English

1. Introducción a la Representación Concurrente

Short description:

Bienvenidos al masterclass sobre las aventuras de la representación concurrente en React18. Soy Maurice de Beer, un instructor de desarrollo independiente y Microsoft MVP. Síganme en Twitter y visiten mi sitio web para obtener más información. Suscríbanse a mi boletín semanal de React para recibir actualizaciones. También recibirán una copia de las diapositivas.

Bien, es hora de empezar. Bienvenidos a todos a este masterclass sobre las aventuras de la representación concurrente en React18. Ayuda si la ventana correcta tiene el enfoque. ¿Quién soy yo? Mi nombre es Maurice de Beer, también conocido como el solucionador de problemas. Soy un Microsoft MVP, entre otras cosas, lo cual no significa que trabaje para Microsoft. Pero de alguna manera hago su marketing de forma gratuita ocasionalmente, lo cual supongo que me deja en desventaja, pero ellos me dan un montón de software gratuito y otras cosas. También soy un instructor de desarrollo independiente. Creo en combinar los dos, porque si desarrollo, entonces cuando enseño, puedo decirle a la gente lo que realmente funciona. Cuando enseño, tengo que seguir pensando en cosas nuevas, otras formas, mejores formas de hacer las cosas, lo cual me mantiene afilado como desarrollador, así que funciona bien juntos. También estoy en Twitter, si quieren seguirme, mi sitio web está aquí y pueden escanear el código QR , también llegarán a mi sitio web y mi dirección de correo electrónico. También publico un boletín semanal, el boletín de React. Ya vamos por el número 310 o algo así, así que llevo haciéndolo durante un tiempo. Pueden escanear el código QR aquí y los llevará a un formulario de registro donde pueden ingresar su nombre y dirección de correo electrónico. Recibirán un boletín por semana, todos los miércoles. Así que el de hoy salió hace aproximadamente una hora, pero la próxima semana saldrá otro. No voy a usar su correo electrónico para nada más, así que no se preocupen por recibir spam y cosas así, o que venda su dirección de correo electrónico a otras empresas. Hay enormes listas de direcciones de correo electrónico filtradas por las grandes empresas, así que mi pequeña lista no va a ser muy influyente allí. Y si no les gusta el boletín, pueden darse de baja en cualquier momento. Recibirán una copia de estas diapositivas, así que si no tuvieron la oportunidad de escanear el código QR o eso, de todos modos lo recibirán.

2. Explorando las características de React 17 y React 18

Short description:

Exploraremos las nuevas características de React 17 y React 18, incluyendo suspense, manejo de errores, renderizado de aplicaciones existentes, suspense list, transiciones y modo concurrente. Tenga en cuenta que no cubriremos todas las características de React 18, como el renderizado del lado del servidor con suspense.

Entonces, ¿cuál es el objetivo del masterclass? Vamos a echar un vistazo a las novedades de la representación concurrente, suspense y en cierta medida lo que no es nuevo. Comenzaremos con algunas cosas en React 17 porque lo que podemos hacer con suspense ahora es bastante importante. Veremos cómo usar suspense, cómo anidar suspense, cómo manejar errores que ocurran dentro de un límite de suspense. Luego pasaremos a React 18, que aún está en vista previa en este momento, no ha sido lanzado aún. Veremos cómo podemos renderizar aplicaciones existentes de React en React 18 usando CreateRoute. Veremos las nuevas capacidades de suspense con cosas como suspense list y transiciones. Veremos qué hace el modo concurrente, cómo podría influir en el rendimiento de su aplicación y cómo lograrlo. Echaremos un vistazo a algunos otros aspectos. No vamos a ver todo lo que React 18 tiene para ofrecer. Hay mucho más. Hay muchas cosas sobre el renderizado del lado del servidor, como actualmente con React 17 no se puede hacer renderizado del lado del servidor con suspense. Con React 18, si usas la API de CreateRoute, puedes hacerlo, pero eso no es algo que vamos a cubrir.

3. Consejos sobre el aprendizaje y la escritura

Short description:

Tu memoria funciona mejor si haces cosas. Intenta hacer los ejercicios en lugar de solo mirar y copiar código. Cometer errores y reconocer errores te ayudará a aprender. Copiar y pegar no es suficiente en el desarrollo de aplicaciones reales. Es beneficioso escribir las cosas.

Un consejo. Tu memoria funciona mejor si haces cosas. Si solo miras la presentación y copias y pegas todo el código de los ejercicios, está bien si quieres hacer eso, pero no recordarás tanto como si realmente intentas hacerlo. Si lo haces, cometerás errores tipográficos. Yo cometo muchos errores tipográficos. Esos errores tipográficos resultarán en errores y reconocerás esos errores cuando vuelvan a ocurrir. Porque cuando realmente construyes aplicaciones, no puedes simplemente copiar y pegar. Sería muy bueno si pudieras copiar y pegar tu aplicación completa. Pero, nuevamente, si puedes hacerlo, cualquiera puede hacerlo, y ¿por qué nos pagan buen dinero por construir aplicaciones si todo lo que necesitas hacer es copiar y pegar? Así que ayuda a tus células cerebrales y escribe las cosas.

4. Prerequisites and Setup

Short description:

Para comenzar, asegúrate de tener Node y npm configurados. Verifica las versiones usando 'node -v' y 'npm -v'. Clona el repositorio inicial desde GitHub e instala los paquetes de npm. Abre Visual Studio Code y ejecuta 'npm start'. La aplicación muestra una lista de usuarios con detalles y una lista de números primos. La renderización puede ser lenta, especialmente con números más grandes. El masterclass incluye diapositivas interactivas con ejemplos de código y enlaces al repositorio de GitHub.

También hay algunos requisitos previos. Ahora, este no es un curso de React para principiantes, así que voy a asumir que todos tienen node y npm configurados, pero por si acaso, vamos a verificarlo. Y luego vamos a comenzar con el repositorio inicial de GitHub, que será la base de todo lo que vamos a trabajar. Lo tengo preparado y te mostraré en un momento cómo configurarlo. Pero primero, los requisitos previos.

Si abres una ventana de terminal y ejecutas node -v o node --version, te mostrará la versión de node, que debería ser algo como node 14 o posterior. No estoy 100% seguro de cuál es la última versión. De hecho, puedo verificarlo haciendo clic en eso. Y, por supuesto, eso se abre en mi otra ventana. Entonces, la versión actual es en realidad 16.13. No es necesario estar en la última versión. Si estás en node 14 o posterior, está bien. Y presumiblemente, 12 o posterior también está bien. Lo mismo con NPM, si ejecutas npm --version o npm -v, te mostrará la versión de NPM. Estoy en la versión 7.24. Creo que la última versión ya está en algo de ocho, pero cualquier versión a partir de la seis debería estar bien. Entonces, si abro una ventana de terminal aquí y la hago un poco más grande, ejecuto node -v, ¿y mencioné algo sobre cometer errores tipográficos? Pero puedes ver que estoy en la versión 14.18 y npm -v me dice que estoy en la versión 7.24, las mismas versiones que en la diapositiva. Luego necesitamos el repositorio, el repositorio inicial. Así que lo tengo en GitHub. Copia ese enlace en un momento en la ventana de chat. Pero eso te llevará aquí a GitHub. Puedes clonar este repositorio. Cópialo, ve a la terminal y haz un git clone con esa URL y eso clonará el repositorio. No es muy grande, así que no debería llevar mucho tiempo. Ingresa a la carpeta y podemos hacer una instalación de npm, npm i o npm ci si prefieres, lo que prefieras y comenzará a instalar todos los paquetes de npm.

Así que copiaré esta URL del repositorio de GitHub en la ventana de chat en Discord. Y en caso de que las personas no hayan llegado a Discord en zoom también. Así que eso está instalado, permíteme abrir Visual Studio Code antes de comenzar realmente la aplicación y mostrarte qué hace. Está creado con create react app. Así que el comando npm start para iniciarlo. Y eso es muy especial ahí. Comienza y sigue abriéndose. En la otra ventana, está bien. Ahí está. Es una aplicación simple, tenemos una lista de usuarios aquí. Si hago clic en el usuario, vemos algunos detalles del usuario. Y vemos algunos detalles sobre su película favorita. Lo mismo aquí. Observa que cuando cargo los detalles, aparecen dos indicadores de carga. Y la película favorita siempre se resuelve primero. Entonces eso se resuelve primero, y los detalles del usuario siempre se resuelven al final. Eso en realidad se hace de forma artificial, porque he agregado un poco de retraso allí. Pero eso es algo de lo que hablaremos varias veces durante el masterclass. También hay una lista de números primos, porque toda buena aplicación empresarial necesita una lista de números primos. Bueno, en realidad tal vez no, pero aquí es útil, no porque sean números primos, sino porque es costoso renderizar una lista de números primos. Y la renderización lenta y costosa es algo que ocurre bastante a menudo con aplicaciones más grandes. Entonces esto es algo artificial, pero cumple un propósito. Ahora, si tomo el control deslizante, puedes ver que puedo moverlo y recalcula esa lista de números. Bastante receptivo aquí. Pero si voy a números más grandes, de repente ya no es tan receptivo. Entonces arrastro el mouse sobre el control deslizante y puedes ver que se retrasa. E incluso si solo hago clic, como estoy haciendo ahora, puedes ver que lleva un poco de tiempo, y si voy a los números muy grandes, hasta un millón, si hago clic puedes ver que no es muy receptivo en absoluto, lo cual es algo que podemos solucionar con el concurrent rendering. De vuelta a las diapositivas. Así que eso es el clon del repositorio. Eso es la instalación de NPM que acabo de hacer.

Ahora, hay muchas partes interactivas en este flujo de trabajo, y prácticamente cada vez que voy a escribir código, habrá, o más bien, cada vez que vaya a escribir código, habrá una diapositiva como esta, y estas diapositivas son enlaces. Si haces clic en ellos, llegarás al repositorio de GitHub y llegarás al commit real, que contiene ese cambio. Entonces aquí en la diapositiva puedes ver algo sobre suspense, y detalles de la película, y cosas así. Y aquí puedes ver con el verde, agregué el límite de suspense al código existente. Por supuesto, puedes ir y copiar esto. Después de todo, es código. Pero como mencioné antes, es mejor usar esto como un ejemplo de qué hacer que copiarlo realmente. Pero, por supuesto, al final, eso depende de ti. También tengo un enlace al repositorio aquí, también un enlace a la presentación de diapositivas. Y copiaré y pegaré esto en la ventana de Slack, o en la ventana de Discord, y en el chat de Zoom también. Porque eso facilita mucho hacer clic en esas imágenes. Como puedo desplazarme hacia abajo aquí y... ¿dónde estaba esa primera aquí? Hago clic en ella y... Esta página tarda demasiado en cargarse, eso es agradable.

5. Breakout Rooms and Task Execution

Short description:

GitHub está fallando. Vamos a usar las salas de grupos de Zoom. Las abriré cuando sea el momento de hacer algo. La mayoría de las tareas son relativamente cortas, así que las abriré en unos cinco minutos. Si has terminado con lo que necesitas hacer, siéntete libre de salir de la sala de grupo y regresar a la sala principal.

GitHub está fallando. Ahí está. Actualicé y apareció. Otra cosa que verás es al Capitán Jean-Luc Picard con su famoso `Make It So`. Básicamente, eso es tu señal para comenzar a hacer algo. Vamos a usar las salas de grupos de Zoom. Las abriré cuando sea el momento de hacer algo. Dependiendo de la tarea real, las abriré un poco más largo o más corto. La mayoría de las tareas son relativamente cortas, así que las abriré en unos cinco minutos. Si has terminado con lo que necesitas hacer, siéntete libre de salir de la sala de grupo, regresar a la sala principal. Si veo que todos han salido de la sala de grupo, no hay necesidad de esperar. Podemos continuar con el siguiente paso. De lo contrario, esperaré a que se acabe el tiempo.

6. Understanding React 17 and Suspense

Short description:

Comenzamos con React 17 y usamos suspense para suspender la renderización de componentes. Suspense se activa al lanzar una promesa, típicamente una solicitud AJAX, dentro de la renderización. Cuando la promesa se resuelve, el componente se vuelve a renderizar. Los errores se manejan mediante límites de error. La biblioteca SWR se puede configurar para usar suspense. Agregar un límite de suspense y un mecanismo de respaldo soluciona las aplicaciones rotas. TypeScript se utiliza en esta masterclass.

Entonces, continuemos. Como mencioné en la introducción, en la primera parte, vamos a empezar con React 17 y cómo podemos usar suspense dentro de React 17 y qué beneficios aporta, y luego construiremos sobre eso cuando lleguemos a React 18. Ahora, veamos qué está sucediendo.

Entonces, esta es la base que necesitamos cubrir para asegurarnos de que podamos trabajar con suspense de React 18 y suspense list y este tipo de cosas. Ahora, con React 17, tenemos el componente suspense y el componente suspense nos permite suspender algún trabajo que se está realizando. ¿Qué significa realmente este trabajo en términos de React? Bueno, suspendes la renderización de un componente o un subárbol de componentes al lanzar una promesa dentro de la renderización, lo cual es un poco extraño. Si piensas en la palabra clave throw en JavaScript o TypeScript, piensas en errores. Lanzas un error. Pero JavaScript te permite lanzar cualquier cosa. Puedes lanzar un número o una cadena. React realmente utiliza eso diciendo, bueno, vamos a lanzar una promesa cuando algo sucede y no podemos terminar la renderización. Y ese algo podría ser cualquier cosa, pero normalmente significa que estás haciendo una solicitud AJAX para obtener algo del servidor. Pero nuevamente, podría ser algo completamente diferente, pero ese sería el caso más común.

Y ese algo del servidor normalmente es una de dos cosas. O bien estás haciendo una solicitud AJAX donde obtienes datos que deseas renderizar. O bien estás cargando componentes de forma perezosa y estás haciendo una solicitud AJAX para cargar de forma perezosa algún código para que puedas renderizar ese componente. Pero aún no se ha cargado, por lo que aún no está disponible. Y cuando se lanza esa promesa, React básicamente dice, okay, vamos a suspender este componente o ese subárbol de componentes, y vamos a esperar a que se resuelva esa promesa. Y una promesa puede resolverse de dos formas. Puede rechazarse, en cuyo caso hay un error, o puede resolverse, en cuyo caso hay éxito. Y si el subárbol de componentes está suspendido y la promesa que lo suspendió se resuelve, entonces React dice, okay, vamos a renderizar ese subárbol nuevamente y presumiblemente cualquier cosa que haya causado la suspensión ahora está terminada, por lo que se renderizará y producirá cualquier elemento DOM o marcado que deseemos. Potencialmente, podría suspenderse nuevamente para obtener más datos. Y en caso de un error, React va a decir, okay, en ese caso hay un error, vamos a llamar a un límite de error o vamos a buscar un límite de error y vamos a dejar que haga su trabajo y si no hay un límite de error, en realidad vamos a cerrar la aplicación.

Ahora la aplicación que estoy usando obtiene datos. Y si vamos a los componentes de origen, y por ejemplo, en usuarios, está este detalle de cuenta. Podemos ver aquí que utiliza el gancho useSWR. Así que ese es un gancho de obtención de datos de Vercel llamado Stale While Revalidate. Por lo que obtiene datos y los vuelve a obtener, etc. Y eso es una solicitud AJAX. Tenemos el código tradicional aquí, manejar errores, si hubo algún error, si no tenemos ningún dato todavía, mostraremos algún tipo de indicador de carga que estamos cargando y eso es en realidad lo que muestra ese spinner. Cuando actualizo, ya tenía algunos datos en la caché. El spinner que aparece aquí, eso es la carga. Y si los datos están ahí, entonces ninguno de estos se va a renderizar y en realidad va a ir directamente aquí. Y por supuesto, si hay un error, déjame introducir rápidamente un error haciendo que esa URL sea inválida. Así que ahora, si hago clic en el usuario, vemos un spinner y luego vemos no encontrado porque esa URL era en realidad inválida. Pero hagámosla válida nuevamente. Resulta que SWR, la biblioteca de obtención de datos, no funciona con suspense de forma predeterminada, pero es muy fácil hacer que lo haga. En el index.js hay esta configuración de SWR, y tiene un contexto de React y proporcionamos algún contexto sobre cómo debe funcionar SWR. Y tiene una opción allí, suspense, que por defecto es false, pero podemos establecerla en true. Y ahora comenzará a usar suspense automáticamente, a menos que sea anulado por alguna otra cosa, podríamos sobrecargar esto en un caso individual, pero no lo estamos haciendo. Así que de repente, todas nuestras solicitudes AJAX han cambiado a suspense. Ahora esto es específico de la forma en que funciona SWR, pero si estás usando react-query, por ejemplo, tiene prácticamente la misma configuración y muchas bibliotecas de React para obtener datos harán lo mismo. Si estás usando React lazy para cargar componentes de forma perezosa, automáticamente entrará en suspense. Ni siquiera puedes desactivarlo, siempre lo hará. Sin embargo, ahora mi aplicación está rota. Si me aseguro de que mis cachés estén vacíos presionando un 5, voy a usuarios, obtenemos un error. Ups, algo salió mal. Lista de usuarios, esa era la lista de usuarios que aparecía antes, se está obteniendo ahora, pero comenzó a usar suspense. Y eso significa que necesitamos tener este mecanismo de respaldo de suspense. Entonces, en algún lugar necesito agregar un límite de suspense. Y normalmente los agrego en varios lugares. Pero comenzaré desde la raíz. Y agregaremos algunos más más adelante. Y queremos algún respaldo, así que tengo un componente de carga. Y eso aún no se resuelve hasta que tenga el insuspense. Ahora eso debería resolver la importación. Así que tengo un objeto suspense. Y ahora si vuelvo a la raíz, y ahora hago lo mismo con las aventuras de renderización concurrente, vemos que realmente obtiene sus datos y usa suspense allí. Y si hago clic en el usuario, carga los datos. Es posible que hayas notado que hay una diferencia de comportamiento porque originalmente cuando hacía clic en el usuario, veíamos dos spinners aquí, uno para los detalles del usuario y otro para los usuarios favoritos. Ahora, de repente, toda la interfaz de usuario se reemplaza por un solo spinner, así que no es muy agradable, diría yo. En realidad, lo solucionaremos en un minuto porque podemos hacer mucho con suspense. Pero si miramos esos detalles de cuenta ahora, es como, bueno, ¿vamos a obtener errores? No, porque con suspense, los errores se manejan de manera diferente, así que podemos deshacernos de ese error. Si no tenemos datos todavía, ¿necesitamos mostrar un indicador de carga? No, porque con suspense, todo ese mecanismo de lanzar una promesa entra en juego. Por lo tanto, nunca deberíamos llegar realmente aquí sin ningún dato, por lo que deberíamos poder deshacernos de eso. Ahora estoy usando TypeScript, y espero que todos sean fanáticos de TypeScript. Soy un fanático de TypeScript y este trabajo de la serie React o trabajo frontend que hago con TypeScript o bastante trabajo backend también. Así que en realidad se queja aquí diciendo, bueno, la cuenta es una cuenta o undefined. Eso es porque la API aquí en el fondo está usando suspense, por lo que sabemos que esta cuenta realmente es una cuenta o se lanzará una promesa.

7. Usando Suspense y Límites de Error

Short description:

En esta sección, aprendimos a usar suspense en React 17. Utilizamos TypeScript para manejar valores potencialmente indefinidos y eliminamos código innecesario. También exploramos la biblioteca SWR para la obtención de datos y agregamos límites de suspense a nuestra aplicación. El comportamiento de carga se puede mejorar, lo abordaremos más adelante.

Nunca va a ser indefinido. Si algo sale mal, no llegaremos aquí, llegaremos a un límite de error, excepto que el tipado realmente no puede saber que estamos usando suspense, por lo que el tipado asume, bueno, la cuenta podría ser indefinida. Entonces, un pequeño truco con TypeScript es que no puedes cambiar eso en línea para que no sea indefinido. Ahora, tengo exactamente lo mismo, pero ahora puedo poner un signo de exclamación detrás de esto diciendo, bueno, data es tal vez una cuenta o indefinido pero sé que nunca es indefinido por lo que siempre es un objeto. Entonces, si verifico el tipo de cuenta, siempre es una cuenta no indefinida, y mis errores de compilación desaparecen. Y he eliminado bastante código. Puedo hacer lo mismo con los detalles de la película, ese error y esa parte de no cargado desaparecen. Ya no necesito ese error. Y esta película siempre es un objeto. Entonces, lo mismo con el signo de exclamación. En la lista de usuarios, tenemos código similar, mucho código similar allí. En realidad, no renombré el data. Solo estoy usando data aquí. Y ahora tenemos un error de compilación justo aquí diciendo objeto posiblemente indefinido. Nuevamente, un signo de exclamación o podría potencialmente poner un signo de interrogación o podría usar otra forma en TypeScript para hacerlo, el operador de fusión nula. Cualquiera funcionará. Así que me deshice de muchas cosas adicionales que no necesitábamos y en realidad tengo algunos elementos de entrada aquí que también puedo eliminar. ¿Dónde estaba el otro? Ahí está, ese es el que estaba buscando. De acuerdo. Así que asegurémonos de que todo funcione. Puedo cargar los usuarios, los data aparecen. El comportamiento de carga no es perfecto como mencioné pero lo arreglaremos más adelante. Entonces, eso es lo básico del suspense. Recuerda ese componente de respaldo o prop de respaldo que debes especificar para el suspense. Puede ser un componente, simplemente puede ser una cadena. Funciona muy bien. Hay un ligero cambio de comportamiento con suspense en React 18 con esa prop de respaldo pero hablaré más sobre eso cuando lleguemos a React 18. Entonces tenemos SWR que estamos usando aquí para obtener data. Una utilidad bastante agradable y conveniente para eso. El cambio que hice allí, agregando suspenses a través de la configuración de SWR y agregando el límite de suspense justo en la raíz de nuestra aplicación. Una especie de último recurso para capturar todos los suspenses. La actualización de las listas de usuarios, los detalles de la cuenta, y los detalles de la película, donde no hay una flecha porque simplemente eliminé código. Bueno, prácticamente eliminé código. Así que no había mucho que mostrar Lo cual funciona muy bien. Y, por supuesto, los resultados. Esto es cuando realmente se está cargando, lo cual no es tan agradable, pero lo arreglaremos en un minuto.

8. Explorando el Manejo de Errores y Límites de Suspense

Short description:

Vamos a abrir las salas de trabajo nuevamente durante más tiempo. Le proporcionaré el enlace del repositorio a Ravi. Luego, exploraremos el manejo de errores, la orquestación de límites de suspense y los resultados obtenidos.

Entonces, vamos a hacer esto. Voy a abrir las salas de trabajo nuevamente. Lo haré durante un poco más de tiempo. ¿Dónde se fueron mis salas de trabajo? La ventana desapareció. Ahí está de nuevo. De acuerdo. Ravi está pidiendo el enlace del repositorio. Así que voy a copiar eso en la ventana de chat para él. Y luego voy a abrir las salas de trabajo durante ocho minutos. Así que puedes seguir este paso y hacer que todo funcione con suspense. Y después de eso, comenzaremos a ver cómo podemos trabajar con errores, capturar errores y luego con diferentes formas de orquestar diferentes límites de suspense juntos y los resultados que obtendremos.

9. Límites de Errores y Manejo de Errores

Short description:

En esta sección, aprendimos sobre los límites de errores en React y cómo manejan los errores en los componentes. Vimos que sin un límite de error, React desmonta toda la aplicación cuando ocurre un error, lo que resulta en una página en blanco para el usuario final. Sin embargo, al agregar límites de errores, podemos capturar errores en componentes específicos y permitir que el resto de la aplicación siga renderizando. También exploramos la anidación de límites de errores y los beneficios de hacerlo. Recomiendo usar el paquete npm estándar de límites de errores de React, que permite reintentar los errores. Por favor, agregue límites de errores a su aplicación. A continuación, pasaremos a la anidación de componentes de suspense.

De acuerdo, entonces suspense. El límite de suspense es relativamente fácil de agregar, pero ¿qué sucede si hay errores? Bueno, si hay errores en un componente normal de React al renderizar, tenemos un límite de error. Y en suspense, eso no es realmente diferente. Así que no tengo que agregar ningún código de error a los componentes individuales que hacen cosas. Simplemente agrego límites de errores al igual que tengo límites de suspense. Y en realidad ya tenía uno por defecto. Si vuelvo a mi index.tsx, correcto, oh, eso no se puede leer. Justo aquí en la raíz de nuestra aplicación, tenía este límite de error con un componente de fallback que realmente lo muestra. Y no tengo ningún código aquí para hacerlo pero normalmente también tendría código aquí que se aseguraría de que el error se envíe a un servidor, se recopile allí, y se use algo como Sentry, etc., para recopilar todos los errores. Así que podría ir y encontrar los errores y solucionarlos. Y en realidad podemos ver eso si introduzco un error, déjame hacer que esta URL sea inválida nuevamente y volver aquí y asegurarme de que no haya data en la caché. Voy a los usuarios, hago clic en el primer usuario, vemos `cargando`. Vemos esta pantalla de error, que es el resultado de estar en el entorno de desarrollo. Pero en tiempo de ejecución, veríamos esto, bueno, algo salió mal, no se encontró el texto de estado, porque es un 404, no encontrado. Ahora, esto solo está ahí debido al límite de error. Vamos a quitar ese límite de error por un segundo y ver qué sucede en una aplicación normal sin un límite de error. Y estoy seguro de que todos lo han visto antes. Actualizaremos la aplicación, haremos clic en el usuario. Obtendremos ese mismo 404. Debido al entorno de desarrollo, obtenemos esto nuevamente, pero en tiempo de ejecución, el usuario final vería esto, una página en blanco completa. No muy informativo, no muy útil, pero porque no hay un límite de error, React básicamente desmonta toda la aplicación. Si voy a la consola en las Herramientas de Desarrollo, en realidad puedo ver que algo salió mal. Y aquí abajo puedo ver la pila completa de componentes que se desmontaron porque no había nada que lo manejara. No había un límite de error que lo manejara. Exactamente lo mismo que sucedería con otros errores. Entonces, deshagamos esto para que el límite de error vuelva. Y ahora, debería poder capturarlo nuevamente. Asegurémonos, sí. Ahora, esto aún no es muy agradable, solo porque un componente falló. Es un poco, aún desmonta toda la aplicación porque solo tengo un límite de error. Y está justo en la raíz de nuestra aplicación. En realidad, solo es un componente que falló. Bueno, lo bueno de los límites de errores, puedo probarlos. Entonces, puedo tomar este límite de error e ir a ese componente de detalles del usuario, que es responsable de los detalles de la cuenta y los detalles de la película favorita. Y podría decir, bueno, quiero un límite de error aquí. Y haré lo mismo alrededor de los detalles de la película. Resolver estas importaciones para que vuelva a compilar. Y ahora, si actualizo, tengo mi aplicación nuevamente, hago clic en el usuario. Llegamos a la página de error de desarrollo. Pero ahora veo que, bueno, solo el componente de detalles del usuario falló y el límite de error alrededor de eso lo capturó. Pero todos los demás aún se renderizan, y puedo ir a otro componente o a otro usuario y aún se renderizará. Por supuesto, ese componente de detalles del usuario no se va a arreglar solo, la URL es inválida, por lo que nunca llegará allí, pero potencialmente puedo cerrar ese límite de error e intentarlo de nuevo. No se va a arreglar solo, por supuesto, pero con algún otro error, podría hacerlo. Podría ser porque la red no estaba disponible. Y ahora, si lo cierro, vuelve y puede recuperar los datos. Por lo tanto, anidar estos límites de errores es realmente agradable y útil. Entonces, ese es el límite de error en la raíz, que ya está ahí, por lo que no es necesario agregarlo. Pero introduzca ese mismo error que acabo de hacer al hacer que esa URL sea inválida. Por lo que obtienes un 404 no encontrado al intentar obtener un usuario específico. Y luego, agregue ese límite de error dentro del componente UserDetails. Y aquí mismo, también puedes ver un componente Suspense. No es necesario agregar eso. Eso es en realidad un pequeño error en mi captura de pantalla que es de una etapa posterior cuando había tanto un error de suspense como un límite de error. Simplemente agregue los límites de error alrededor de AccountDetails y alrededor de MovieDetails allí. Entonces, estos dos. Y luego, deberías poder capturar el error solo en ese componente individual y hacer que todos los demás se rendericen. Y en realidad estoy usando el paquete npm estándar de límites de error de React aquí, que es realmente agradable, y que permite reintentarlo. Entonces, si haces clic en esa cruz, en realidad lo volverá a intentar. No creé un límite de error personalizado ni nada. Este es un paquete realmente agradable y se recomienda encarecidamente usarlo en su aplicación. Así que por favor, ve y agrega estos. Voy a abrir las salas de trabajo durante 5 minutos nuevamente. Después de eso, vamos a ver cómo anidar componentes de suspense, al igual que podemos anidar límites de errores. Porque en muchos aspectos, funcionan de manera muy similar. Pero ese es el siguiente paso. En este paso, creemos ese límite de error anidado y veamos qué sucede cuando ocurren errores. Así que todos vuelvan. ¿Todos tuvieron éxito con este paso? El límite de error captura errores. De acuerdo. Pulgar arriba.

10. Anidando Límites de Errores y Límites de Suspense

Short description:

El componente suspense captura promesas que se lanzan, mientras que el límite de error captura errores. React comienza en el componente que activa el suspense y recorre el árbol para encontrar el primer límite de error. La diferencia entre los dos es que el límite de error tiene una propiedad de fallback que puede suspender potencialmente, mientras que el componente suspense está dentro del límite de error. Se recomienda tener un límite de error en la raíz de la aplicación para manejar todos los errores. Anidar límites de error y límites de suspense es útil. Colocar un límite de suspense alrededor de la aplicación y un límite de suspense alrededor del componente específico puede mejorar la experiencia del usuario. Sin embargo, es importante considerar el impacto en el rendimiento de la aplicación. Mantener una lista de usuarios y mostrar un spinner para los detalles del usuario se puede lograr anidando componentes suspense.

Muy bien, todo parece bien. Entonces, en realidad hay dos preguntas. Una de Alexi. Pensé que el componente suspense captura errores que son lanzados por hooks u otros componentes hijos. ¿Cómo capturaría el componente límite de error el error si el suspense es su hijo? En realidad, el componente suspense no captura errores. Captura promesas que se lanzan. Y si se lanza una promesa, entonces el límite de suspense entra en acción, incluso si se lanza otro error o algo más, una cadena o un número, pero siempre debes lanzar objetos de error, entonces el límite de suspense lo ignorará. Y dejará que el límite de error se encargue de eso. Entonces- Eso tiene sentido, lo único es que si la promesa es rechazada, ¿también se considera un error? Sí, si la promesa es rechazada, eso es un error y se tratará de la misma manera que si se hubiera lanzado un error en primer lugar. Entonces, el límite de error podría capturarlo. Y en ese caso, React comienza en el componente que activa el suspense y recorre el árbol para encontrar el primer límite de error desde allí. No desde el componente suspense, sino desde el componente original que inició el suspense.

Y hubo otra pregunta y solo abriré Discord por un momento para mostrarlo. La diferencia entre los dos y el primero tiene el límite de suspense y dentro de él está el límite de error y dentro de eso está el componente. Y en el segundo, tenemos el límite de error en el exterior, el suspense dentro de él y los componentes dentro de eso. Si hay alguna diferencia entre los dos, sí. Pero eso dicho, en términos prácticos, probablemente no. La única diferencia es que, si observas el límite de error aquí, tiene una propiedad de fallback que podría suspenderse potencialmente. Ahora es bastante improbable que eso suceda, pero si hay un error, podría cargar perezosamente diferentes componentes para mostrarlo. No recomendaría hacer eso porque si tienes un error debido a algún problema de conectividad de red, intentarás cargar un componente de error que también fallará debido al mismo problema de conectividad de red. En ese caso, podría suspenderse y sería capturado por los mismos componentes suspense. Y aquí es al revés. Si el límite de error tiene alguna razón para suspender con su visualización de error, y no puede hacerlo porque el suspense está, o debería decir el componente suspense está dentro de él. Pero ahora, en el caso del fallback del suspense, si eso es un error, bueno, el límite de error puede capturarlo. Lo que normalmente hago es en la raíz de mi aplicación, tengo un límite de error en la raíz porque quiero ser notificado de todos los errores que ocurran donde sea que ocurran. Y normalmente no deberías hacer ningún trabajo asíncrono por lo que al menos no hay nada que suspenda. Si envío data a un servicio de recopilación de errores, no lo enviaré de inmediato allí porque si hay problemas de conectividad, es posible que nunca llegue. Así que lo pondré en una cola y eventualmente enviaré las cosas y almacenaré esa cola en el almacenamiento local o en la base de datos del índice para que incluso si el usuario actualiza el navegador, esos errores no se pierdan. Eventualmente podrían perderse, pero no en circunstancias normales. Por supuesto, si el usuario nunca se conecta, no lo recibiré pero en circunstancias normales eventualmente recibiré ese error. Entonces, Martina dice, pero el primer ejemplo es en realidad lo que tenemos ahora en la aplicación porque tenemos un suspense alrededor de la aplicación y un límite de error alrededor de los detalles del error. No exactamente, porque también tenemos un límite de error justo en el nivel del índice. ¿Dónde está mi index.tsx? Ahí está. Entonces aquí, donde renderizo lo primero es un límite de error que es como el capturador general en caso de un error que no se maneja localmente, será capturado por eso. Y luego dentro de eso, tengo el límite de suspense que también es como un capturador general. Aún no hemos anidado suspense pero normalmente suspendería más cerca de donde realmente quiero. Y este es como un límite de suspense de último recurso para asegurarme de que mi aplicación no falle. Entonces, el límite de error está en el exterior, el suspense dentro, y luego, potencialmente, o lo más probable es que tenga versiones anidadas de esos dos dentro de otros componentes donde puedo manejar las cosas localmente. Así que espero que eso aclare esos dos puntos. Pasemos al siguiente paso. Porque como mencioné, podemos anidar límites de error, pero también podemos anidar límites de suspense. Y eso es bastante útil. Porque si vuelvo a mi aplicación por un momento, comencemos aquí, actualizo para asegurarme de que todo esté en orden. Actualizo para asegurarme de que no haya nada en la caché, y veamos qué sucede con una red realmente lenta. Entonces, lo he configurado para simular una red 3G lenta en este momento, que es bastante lenta. Irrealísticamente lenta para la mayoría de las aplicaciones, pero ahora si hago clic en usuarios, vemos que toda la página está prácticamente en blanco. La barra de navegación desaparece, y solo vemos ese spinner. Hago clic en el usuario y nuevamente, toda la página está en blanco, e incluso no vemos la barra de navegación. Y si vemos una lista de usuarios, ahora si hago clic en el segundo usuario, eso desaparece, la barra de navegación desaparece. Así que está bien. Los límites de suspense funcionan. Son capturados, pero es un poco dramático, y está eliminando demasiado. Entonces, lo que podemos hacer es decir, bueno, tomemos este límite de suspense y veamos qué hay dentro de esta aplicación. Bueno, aquí podemos ver el enrutador del navegador para React Router, y podemos ver la barra de navegación, la barra de navegación en la parte superior, y luego cómo se manejan las rutas. Bueno, en este caso, no se hacen con lazy, pero es muy probable que se haga. Entonces es muy probable que esos suspendan. Entonces, poner un límite de suspense alrededor de esto es en realidad un muy buen lugar. Entonces, reanudemos esas importaciones, y veamos cuál es el efecto. Entonces volvemos aquí. Simulo la red 3G nuevamente. Vamos a Usuarios, y ahora todavía vemos ese spinner de carga, pero la barra de navegación permanece en la parte superior. Entonces hago clic en el usuario, la lista de usuarios desaparece, pero la barra de navegación permanece. Así que un poco mejor, pero no del todo bien. Porque ahora, si cambio entre usuarios, me gustaría mantener esa lista de usuarios y solo mostrar un spinner aquí para los detalles del usuario. Entonces, dentro de los detalles del usuario aquí, podría decir, bueno, realmente quiero otro componente suspense aquí. Y también necesito resolver estas importaciones. Ahora todo eso está dentro de un límite de suspense. Entonces, ahora si hago clic en un usuario, eso se mantiene. Pero solo, permíteme cambiar aquí nuevamente. Hago clic en el usuario y muy brevemente, podríamos mostrar el spinner allí.

11. Anidando Límites de Suspense

Short description:

Podemos anidar límites de suspense para lograr una interfaz de usuario decente. React 18 respeta null como el fallback para suspense, a diferencia de React 17. Anidar componentes suspense nos sirve incluso con React 17. Pasemos a suspense en paralelo, que es similar a los límites de error.

Y ahora obtenemos un spinner aquí. Y potencialmente podríamos decir, bueno, quiero que ese primer encabezado esté fuera del suspense. Así que los detalles del usuario aparecen de inmediato. Ahora, si hago clic en el usuario, vemos los detalles del usuario, y solo aparece la parte de detalles y película favorita cuando los datos se cargan. Entonces no es exactamente como se veía al principio, pero está bastante cerca. Y en realidad creo que esta es una forma bastante decente de anidar límites de suspense y obtener una interfaz de usuario bastante decente.

Entonces, anidando límites de suspense, puedes anidarlos como quieras. Y básicamente, cada vez que un componente hace suspense, React comenzará a recorrer el árbol de componentes. Comenzará en el componente que hace suspense. Mirará a sus padres. Si esos componentes hacen suspense, los usará, si no, subirá un nivel, y así sucesivamente. Así que encontrará el límite de suspense más cercano y lo usará para suspender la aplicación. Si hay varios componentes haciendo suspense, cada uno hará este pequeño truco por sí mismo y varios componentes suspense pueden estar activos al mismo tiempo.

Ahora hay un cambio de comportamiento en React 18. Todavía estamos en la versión 17, así que no puedo mostrarlo aún. Pero con la interfaz de fallback que especificamos aquí mismo, esta, tengo un componente, un componente de carga que muestra ese spinner. Podría poner algún texto aquí, básicamente cualquier cosa que sea válida para que React la renderice podría ir allí. Y una cadena es perfectamente válida. Pero React también dice que null es perfectamente válido. Puedo tener un componente que en su renderizado devuelve null y eso significa básicamente que no es necesario renderizar nada aquí. Bueno, si haces eso en React 17, React 17 ignorará ese límite de suspense nulo. Lo tratará como si no existiera. Y seguirá subiendo por el árbol, encontrando el siguiente. Con React 18, en realidad lo respetará y dirá, está bien, no quieres renderizar nada, entonces está bien, no vamos a renderizar nada hasta que esto se resuelva. Es bastante improbable que te afecte. No he visto ningún código de producción donde la gente use null como fallback para suspense, pero es posible y es un cambio de comportamiento.

Aquí está el primer límite de suspense que agregué, el primero anidado, y luego tuvimos este resultado. Y luego entré en el componente de detalles de la película y agregué otro límite de suspense justo ahí. Y obtuvimos este resultado cuando comenzamos a hacer clic en Usuarios, lo cual, sé que la interfaz de usuario no siempre es una gran herramienta, no soy realmente un experto, pero me gusta este resultado y sirve bastante bien en las aplicaciones. Entonces, incluso con React 17, anidar estos componentes suspense nos sirve muy bien. Así que sigamos y hagamos esto. Es otra tarea de cinco minutos. Así que voy a abrir la sala de grupos de trabajo de nuevo en cinco minutos. Antes de hacerlo... Hubo un par de preguntas más. Entonces, de Raffy... Así que el recomendado es el dos, supongo que te refieres a este en Slack. Ese es el que recomiendo. Y esta ya la respondí. De acuerdo. Así que voy a abrir las salas de grupos de trabajo y nos vemos todos aquí de nuevo en cinco minutos. Así que todos están de vuelta. ¿Todos tuvieron éxito con este paso y el siguiente límite de suspense funcionando? En realidad, estaba obteniendo un error, pero no sé por qué, como en los detalles del usuario, el componente de lista de usuarios, estoy obteniendo un error en la línea donde estamos intentando iterar sobre data. ¿Esta línea? Sí, sí. ¿El error es en tiempo de ejecución? Sí, en tiempo de ejecución. En tiempo de ejecución, eso no debería ser así. Sí, ese era el problema. Como, sí, poner un signo de interrogación aquí significa que funcionará, pero incluso un signo de exclamación, que le dice al compilador, como sé que data nunca es undefined, trátalo como un objeto, está bien, realmente es un array, confía en mí. Esa no es una comprobación en tiempo de ejecución. Eso es muy común. Probablemente solo me equivoqué con el suspense en algún lugar de arriba, tal vez. Sí, simplemente no lo sé. Parece que funcionó. Lo que podrías revisar es aquí, si tienes este suspense en la configuración de SWR. No. Esa es la parte que me falta, en realidad. Sí, gracias. Sí, suspense. De acuerdo, resuelto. Gracias. De nada. Entonces, hagamos suspense en paralelo porque hicimos límites de error en paralelo y mencioné un par de veces que suspense y límites de error son muy similares entre sí y hacen prácticamente lo mismo excepto que uno lo hace cuando se lanza una promesa y el otro cuando se lanza un error. Pero aparte de eso, bueno, obviamente no son exactamente iguales, pero son muy similares en la forma en que se trabajan con ellos. Y tuvimos que, ¿dónde estaba mi código? Y eso es detalles del usuario. Tenemos límites de error aquí en paralelo, pero solo tenemos un solo suspense.

QnA

Suspense en Paralelo y Manejo de Preguntas

Short description:

Podemos agregar suspense en paralelo duplicando componentes suspense para diferentes detalles. Sin embargo, la interfaz de usuario puede no ser perfecta y React 17 no proporciona mucho control sobre las suspensiones independientes. Con React 18, tendremos componentes de lista de suspense que coordinan múltiples límites de suspense y permiten un mayor control sobre el renderizado y la resolución. Después del descanso, se hizo una pregunta sobre cómo hacer compatible una capa de red existente con suspense y se mostró una demostración de cómo lanzar promesas en código personalizado.

Bueno, ¿por qué no podemos agregar eso en paralelo? Bueno, podemos. Solo puedo duplicar estos. Así que tengo el suspense alrededor de los detalles de la cuenta y tengo un suspense diferente alrededor de los detalles de la película. Y ahora, si vuelvo a la aplicación, asegurémonos de que nada esté bien, obtenemos dos spinners nuevamente si hago clic en el usuario. Uno para la película, su película favorita, uno para los detalles de su usuario. Cada uno se suspende independientemente del otro y cada uno se reanuda independientemente del otro. Y al igual que antes, si hago el suspense dentro o fuera del límite de error, déjame cambiar uno de ellos, no importa. Es solo una cuestión de, está bien, si este fallback arroja un error, entonces este límite de error puede capturarlo. Y aquí, si este componente de fallback se suspende, entonces este suspense puede capturarlo. Pero como mencioné antes, probablemente no sea la idea más sabia. Aquí, realmente no me importa cuál sea el orden, cuál anidas dentro del otro, en la raíz de mi aplicación, creo que el límite de error siempre debería estar fuera. Aquí, no es tan importante. Y seguirán funcionando exactamente de la misma manera. Ahora esto funciona y es muy bueno, pero una cosa que personalmente no me gusta de la interfaz de usuario, pero nuevamente, no soy un experto en UI. Como dije antes, es el resultado de la Película Favorita primero. Entonces, vemos dos spinners. Luego vemos User Detail Spin, nuestra película favorita con los detalles reales. Y luego User Detail Resuelve su data. Entonces, la película favorita se empuja realmente hacia abajo. Realmente no me gusta eso en términos de UI. Que puedo hacerlo, que tengo la capacidad de organizarlo de esa manera, es realmente agradable. Que la interfaz de usuario funcione de esa manera, meh, no estoy tan contento al respecto. Pero en este caso, en realidad lo hice intencionalmente. Puede que lo hayas notado, pero si entramos en estos componentes. En la URL, tengo un servicio aquí donde puedo especificar un tiempo de espera específico. Entonces, cada detalle de la cuenta esperará un segundo antes de responder. Y cada detalle de la película aquí esperará medio segundo antes de su respuesta. Entonces, siempre responderá más rápido. Hice eso intencionalmente para mostrar exactamente este comportamiento de los dos usuarios y los data que se empujan hacia abajo. En la aplicación real, no sabes cuál es el orden. Y a veces, el primero se resolverá, a veces el segundo. En una máquina de desarrollo, típicamente responderán bastante rápido porque típicamente ejecutas cosas localmente y todo es rápido en producción. Va por Internet o tal vez por una red de la empresa, pero las cosas probablemente serán más lentas y no tan buenas. Con React 17, no podemos hacer mucho al respecto. Ambos componentes suspense serán independientes entre sí. Harán su propio suspense. Harán sus propias reanudaciones y eso es todo. No obtenemos más control. Lo único que podemos hacer es decir, bueno, no quiero este comportamiento. Luego, coloca un límite de suspense alrededor de ambos componentes que hacen suspense. Cuando lleguemos a React 18, veremos los componentes de lista de suspense, y el componente de lista de suspense coordinará múltiples límites de suspense como este, y podremos controlar cómo reaccionarán o cómo se renderizarán juntos y cuándo se resolverán, lo cual es muy agradable. Pero con React 17, no tenemos exactamente eso todavía. Entonces, el suspense en paralelo. El cambio que hice, en este caso, solo tengo dos suspense, pero los límites de error pueden permanecer allí como los tenía en mis componentes. Básicamente, hacer que se suspendan en paralelo, y tenemos este resultado, que funciona bastante bien, excepto en este caso, la forma en que cambia la interfaz de usuario no es exactamente perfecta. Pero lo arreglaremos cuando instalemos React 18.

Hola, todos de vuelta del descanso. Es hora de continuar. Antes de continuar, Alexei hizo una pregunta interesante en la ventana de chat de Zoom. Estamos usando el gancho use SWR para proporcionar una API de búsqueda compatible con suspense para nuestros componentes, pero ¿qué pasa si ya teníamos una capa de red en nuestra aplicación existente? ¿Cómo podríamos hacerla compatible con suspense? ¿Y vamos a pasar por eso? Bueno, no estaba planeando hacerlo, pero puedo hacerlo brevemente. No voy a crear una biblioteca completa. Y la segunda parte me da curiosidad sobre las API de bajo nivel de la función suspense, cómo puedes lanzar una promesa en tu propio código. Y puedo mostrar eso relativamente fácilmente. ¿Dónde está mi aplicación aquí? Así que veamos qué sucede realmente si lanzo suspense. Supongamos que estoy en los detalles del usuario aquí y agreguemos un botón en la parte superior. Suspense me o algo así. Y tenemos un evento de clic. Oops. Y ahora necesitamos hacer algo aquí. Así que tendremos un controlador de eventos y lo mantendré simple en línea. Ahora, esto necesita renderizarse o esto necesita suspenderse cuando lo renderizamos. Entonces realmente no puedo hacerlo aquí en este on click directamente porque entonces estamos en un controlador de eventos y no estamos realmente renderizando. Entonces necesito introducir un poco de estado. Entonces haremos const suspend me. El tipo es difícil. Nuevos estados y comenzaremos con false. Y luego aquí dijimos suspend me a true. Ahora, por supuesto, eso realmente no hace nada todavía. Entonces, si abro un usuario, tenemos suspend me y puedo hacer clic en él, no sucede nada. Bueno, algunos cambios de estado, pero no estamos usando ese estado, pero ahora puedo usar este estado.

Suspender y Instalación de React 18

Short description:

Exploramos cómo suspender un componente usando una nueva promesa. Al lanzar una nueva promesa, podemos suspender el componente. La resolución de la promesa después de un tiempo de espera resuelve la suspensión. Esta técnica se puede utilizar en cualquier función llamada desde el ciclo de renderizado. Mover el código fuera del ciclo de renderizado, como en un controlador de eventos, no causará suspensión. Luego pasamos a React 18 y discutimos el proceso de instalación. La última versión de React 18 se puede instalar usando npm, y hay diferentes etiquetas disponibles, incluyendo 'latest' y 'next' para la versión alfa.

Y aquí podría ver algo como si suspendMe, lanzar una nueva promesa. Y eso realmente hará que este componente se suspenda. Y eso se queja porque necesita una función de devolución de llamada. Y la dejaremos vacía por ahora. Entonces, ahora si abro el usuario y hago clic en suspendMe, en realidad hemos suspendido nuestro componente.

Ahora esta promesa nunca se resuelve ni se rechaza. Así que esto permanecerá suspendido para siempre. Así que vamos a resolverlo realmente. Entonces, el constructor de la promesa toma una función que recibe una función de resolución y rechazo, pero solo la resolveré por ahora. Así que haremos un setTimeout y llamaremos a esa resolución después de dos segundos. Entonces, ahora si hago clic en el botón de suspensión, en realidad necesito establecer la bandera de suspensión en falso, de lo contrario, se volverá a renderizar e inmediatamente se suspenderá nuevamente. Entonces estableceremos la bandera de suspensión nuevamente en falso y volveremos a renderizar. Y en realidad, ¿quiero hacer eso aquí? Creo que esto debería estar bien. Vamos a verificar. Así que tenemos useDetailsLoaded, está suspendido y después de dos segundos, esperaba que se resolviera, pero aparentemente no lo hace. Entonces, ¿por qué es eso? Tal vez necesito hacer esto primero. Vamos a verificar. ¿No deberías invocar a la resolución? De hecho, lo estoy haciendo. Puedo hacerlo explícitamente, pero debería hacerlo pasando la referencia de la función al setTimeout. Eso debería ser lo mismo, pero vamos a verificar. Tal vez eso sea realmente la diferencia. ¿Deberíamos establecer esto dentro de esta devolución de llamada? ¿Establecer el suspendMe dentro de la devolución de llamada? Entonces, después de un tiempo de espera, como después de 2000 milisegundos, deberíamos establecer suspendMe en falso. ¿Aquí, quieres decir? Sí, sí, sí, dentro de esa devolución de llamada. Eso suena razonable. Veamos si eso lo soluciona. Entonces se suspende. Eso fue todo. Gracias. Entonces ahora se suspende. Espera dos segundos y luego se resuelve. Entonces, la esencia de la suspensión es realmente muy simple. Es solo esta cosa, lanzar una nueva promesa. Y con eso, bueno, eso no es específico de React. Puedes hacer esto en cualquier lugar. Puedes hacer esto en el hook. Puedes hacer esto en la biblioteca. Puedo poner esto en cualquier función que quiera. Es solo cuestión de que debe ser llamado desde este renderizado. Si muevo todo este código dentro de ese controlador de clics, elimino esto por un segundo. Ahora no va a hacer nada. De hecho, eso ni siquiera funciona. ¿Por qué... Creo que tengo un corchete de más, creo. ¿No? Tenías un corchete de menos. Oh, cierto. Gracias. Entonces ahora no va a hacer nada. ¿Ves? Sin suspensión, nada. Porque no se hace en el renderizado. Está en un controlador de eventos. Entonces, si muevo esto de vuelta, solo copio todo, y establezco suspendMe nuevamente, entonces debería estar bien. Suspender durante dos segundos, y vuelve. Entonces, con eso, realmente no es tan difícil de integrar en bibliotecas existentes. Solo tienes que asegurarte de estar dentro del ciclo de renderizado, y con un hook, eso es fácil. Lo dejaremos así.

¿Dónde están mis diapositivas? Ahí están. Entonces, con eso fuera del camino, vamos a cambiar a React 18, y vamos a ver qué nos trae React 18, tanto con estos límites de suspensión, como con ese componente de números primos, que es realmente lento y pesado. Pero por supuesto, lo primero que tenemos que hacer es instalar React 18, y si miramos en npm, Este es el paquete de React, pero con React DOM, vería exactamente lo mismo. Puedo ir a las versiones. Y aquí, verás que hay diferentes versiones. Ahora tenemos aquí una etiqueta latest. Esa es la versión normal que usas cuando haces npm install de React. También hay esta versión con la etiqueta next, que actualmente apunta a 18.0 alfa, que a partir del hash, y luego está esta fecha del 23 de octubre. Y hoy es 27, así que eso tiene cuatro días. Pero en realidad fue lanzado, dice aquí, hace dos días. Así que creo que eso fue el viernes pasado o algo así y lanzado el lunes. Ahora, en este momento, también hay esta alfa y versión experimental. Y alfa y next son en realidad lo mismo. Experimental es diferente. En realidad, también es la misma versión, lo cual puedes ver por este hash.

Instalación de React 18 y Actualización de Código

Short description:

Para instalar React 18, utiliza la rama 'next' con la etiqueta next. Utiliza 'npm install React-at-next' y 'React-dom-at-next' con la opción '--force' para instalar las dependencias. React Router DOM 6 es compatible con React 18 y React 17. La API del enrutador ha cambiado, ahora se basa en hooks. Utiliza el hook 'useRoutes' para definir las rutas. React DOM.render ya no es compatible en React 18, utiliza React root en su lugar. Actualiza el código para utilizar 'createRoot' y pasa el elemento DOM como parámetro. TypeScript puede mostrar un error de compilación, pero se puede solucionar utilizando el signo de exclamación para afirmar el tipo de 'getElementById'.

Aún tiene el mismo hash, pero no tiene la versión 18.0.0. Así que en este momento, los tres funcionan de la misma manera. El objetivo aquí es que 'next' eventualmente se convierta en la versión más estable de los candidatos a lanzamiento de React 18, etc. Alpha siempre será algo menos estable, y Experimental básicamente será compilaciones diarias. Entonces, si estás buscando la próxima versión a lanzar, la rama 'next' es la que te interesa lanzar con la etiqueta 'next'. Así que podemos ir e instalar eso. Ahora, si solo haces una instalación de MPM de React-at-next y React-dom-at-next, en realidad fallará debido a las dependencias. No estoy seguro al 100% de cuál es el caso. Pero con '--force', en realidad funcionará. ¿Dónde está la consola? Así que limpiemos esto. MPM install React-at-next y React-dom-at-next con '--force'. Eso debería instalarse bastante rápido porque esos paquetes son bastante pequeños. Están instalados. Y por ejemplo, puedes ver con SWR. Dice que quiere React 16.11 a 17. Entonces, esa es una de las bibliotecas que realmente se quejaría y rechazaría la instalación sin '--force'. Otra biblioteca que potencialmente podría ser un problema. Si voy al archivo package.json, puedes ver lo que tengo. Tengo React Router DOM aquí. Comúnmente utilizado React Router. Ahora, si usas la versión normal, la versión cinco, no es compatible con React 18. Así que en realidad estoy usando la versión beta de React Router DOM 6, que es compatible con React 18. Y como ya hemos notado, también es compatible con React 17. No estoy seguro cuál es la versión más reciente, la versión más antigua para React Router DOM 6, pero llega a React 16 algo. Entonces, versiones relativamente recientes de React funcionarán perfectamente bien con él. Ahora la API ha cambiado. No es realmente parte de la presentación, pero aún es útil verlo. Quería ir aquí, app route. El enrutador ahora se basa en hooks. Así que ahora hay un hook llamado 'useRoutes' al que le pasas una matriz de las diferentes rutas y las diferentes opciones. Como aquí, estoy diciendo que para los usuarios use el elemento 'user list' y para los números primos use 'prime numbers'. Y para el inicio, solo tengo un marcado en línea aquí. Así que ha cambiado un poco. React Router DOM cinco no funcionará, al menos no completamente, con React 18. Así que ten cuidado con esa actualización. Pero eso es React Router o una especie de React y React DOM instalados. Volvamos a iniciar la aplicación y veamos si aún funciona. Cargando punto punto punto. Y ahí vemos 'parling building in London' de nuevo. Y vemos los usuarios y todo eso aún funciona. El límite de suspense funciona, ¿esto aún funciona? Sí, eso funciona. Los números primos aún funcionan con números un poco más grandes. Aún es lento. Así que parece que nuestra aplicación funciona, pero realmente no ha tenido ningún efecto observable significativo. Ahora esto, hasta que vaya a las herramientas de desarrollo. Si abro el registro de la consola y lo establezco sin limitación, esa es la que quería, la consola. Aparece un mensaje aquí. Advertencia, React DOM.render ya no es compatible en React 18, utiliza React root en su lugar. Hasta que cambies a la nueva API, tu aplicación se comportará como si se estuviera ejecutando en React 17. Entonces, aunque no sea compatible, funciona, pero en realidad no estamos utilizando ninguna de las capacidades de React 18. Actúa como si fuera React 17. Bueno, eso no es lo que queremos. Así que vamos a arreglar eso. Volvamos al index.tsx. Aquí tenemos nuestro React DOM.render, que no deberíamos usar. Dice que use createRoot. Y React dom.createRoot devuelve un objeto y ese objeto todavía tiene una función de renderizado. Así que se convierte en algo como esto, excepto que el elemento DOM en el que queremos renderizar se convierte en un parámetro para createRoot. Así que se ve así. Lo único es que hay un error de compilación aquí. Tipo null no asignable a elemento o documento o fragmento de documento o comando. La razón es que createRoot, si miro la tipificación, está tipado como uno de esos parámetros, pero no como null o undefined. Esa no es una opción válida. Y si miro getElementById. Devuelve un elemento HTML o null porque si especificas un ID que no existe, getElementById no arroja un error, simplemente devuelve null. Sabemos que este elemento existe, por lo que TypeScript soluciona el problema con el signo de exclamación diciendo TypeScript, sé mejor. Sé un mejor tipo. TypeScript, sé mejor. Sé que getElementById siempre devuelve un elemento HTML, no un null.

Renderizado de React 18 y Nuevos Hooks

Short description:

Estamos utilizando el renderizado de React 18, pero la aplicación sigue siendo lenta. React 18 introduce nuevos hooks, incluyendo useDivertValue, useTransitionHook, useMutableSource y useOpaqueIdentifier (o useID). useOpaqueIdentifier es útil para enfocar automáticamente los campos de entrada asociados con etiquetas. Puede ser desafiante lograr este comportamiento al renderizar tanto en el servidor como en el cliente, pero useOpaqueIdentifier simplifica el proceso. Ten en cuenta que useOpaqueIdentifier puede ser renombrado a useID en la versión actual de React 18.

Y ahora estamos contentos de nuevo. Y ahora, si vuelvo a la aplicación y la actualizo, no hay más errores en la consola. Se renderiza correctamente. Y estamos utilizando el renderizado de React 18 y todo eso. Dicho esto, sigue siendo lento. Estamos utilizando el renderizado concurrente, pero realmente no podemos decirlo aún porque todavía no estamos aprovechándolo, pero lo estamos utilizando. Así que aquí están las actualizaciones en el package.json. Tengo versiones ligeramente antiguas aquí. Las versiones se lanzan con bastante frecuencia, pero eso no debería, al menos espero que no porque sé que hay un cambio en el código que mencionaré cuando lleguemos allí, pero eso no debería afectarnos, espero. Entonces, el cambio en el index.tsx a react-dom.createRoot. Ahora, si estás utilizando TypeScript, podrías preguntarte cómo es que esto realmente se compila y funciona, porque createRoot no existía en React 17. Bueno, tengo este archivo tsConfig, que obtienes de forma predeterminada si creas una aplicación de React usando la opción de plantilla TypeScript, pero le agregué una cosa, y es esta línea. Los typings de react-dom y react-typings no están incluidos en el paquete original de MPM, provienen de DefinitelyTyped. Y de forma predeterminada, buscará los typings estándar allí, pero los typings de DefinitelyTyped contienen la próxima versión. Así que ya le dije a TypeScript que mire estas próximas versiones de React, por lo que ya sabe que la nueva API existe. Por eso no obtuve un error de compilación allí. Eso ya se agregó anteriormente. Pero si creas una nueva aplicación o si tienes una aplicación existente y vas a actualizar a React18 antes de que se lance, entonces estos tipos no se actualizarán, entonces tendrás que hacer lo mismo. Pero ahora mismo eso ya está hecho, así que no hay necesidad de preocuparse por eso. Así que el cambio allí. Y por favor, hazlo. Entonces, React18 en realidad nos brinda muchas características nuevas. Los nuevos hooks, hay muchas cosas nuevas para el renderizado en el servidor que mencioné y que no vamos a ver, pero ahora es posible el renderizado en el servidor con suspense. Pero los nuevos hooks son bastante interesantes y voy a ver algunos de ellos. Hay uno nuevo llamado useDivertValue que puede ser útil en escenarios de rendimiento. Ahora no vamos a usar eso. No ayuda mucho con esos números primos pero ese es el tipo de caso donde podría ayudar potencialmente. En este caso, simplemente es demasiado lento y usar DivertValue no lo solucionará. Pero básicamente, DivertValue te permite decir, hay un valor que cambia con frecuencia y no me importa particularmente todos los cambios. Solo dame algunos cambios y dame el valor final cuando se estabilice. Si miras la documentación para la próxima versión de React, todavía está un poco desactualizada. Dice que hay un parámetro allí donde puedes especificar cuánto puede retrasarse eso en realidad no existe en el código actual. Así que la documentación está ligeramente equivocada allí y no hay mucho que puedas configurar realmente. Insertas un valor, que cambia con frecuencia y obtienes un valor de salida. Hay un useTransitionHook que es muy útil para las transiciones de estado y en realidad lo usaremos para un par de escenarios diferentes. Así que lo dejaré para más adelante. Hay un nuevo hook llamado useMutableSource que no está realmente destinado a desarrolladores finales o desarrolladores de aplicaciones. Está más destinado a desarrolladores de bibliotecas como Redux, MobX, ese tipo de cosas. Y está destinado a evitar el desgarro de la interfaz de usuario. Ahora volveré más tarde y explicaré qué significa el desgarro de la interfaz de usuario y cómo puede suceder con React 18 porque eso es algo que antes no podía suceder. Y luego el motivo del nuevo hook useOpaqueIdentifier o tal vez en realidad se llame useID. No estoy completamente seguro todavía porque cuando creé estas diapositivas todavía se llamaba useOpaqueIdentifier pero también tenía un prefijo inestable y anunciaron la semana pasada que lo iban a renombrar a useID y eliminar ese prefijo inestable. Así que no estoy cien por ciento seguro de lo que hay en la versión actual de React que acabamos de instalar si ya ha sido renombrado allí o si aún no lo ha sido, pero ese es el hook con el que vamos a jugar primero. Y déjame mostrarte dónde querrías usarlo. Si vuelvo a la lista de usuarios tenemos un formulario de entrada aquí. Ahora, estos campos están deshabilitados, pero pueden recibir el enfoque. Y puedes ver que hay una barra de enfoque alrededor. Esto es estilo bootstrap estándar, por cierto. Ahora, con bastante frecuencia en un formulario HTML, si haces clic en la etiqueta asociada a un campo de entrada, como estoy haciendo clic en apellido ahora, entonces el campo de entrada asociado se enfocará. Pero eso no sucede aquí. Podría conectar esos campos manualmente, pero eso es un poco tedioso. Y realmente querrías hacerlo automáticamente. Ahora, eso no fue particularmente difícil de hacer con un hook personalizado en React siempre y cuando todo se renderizara en el lado del cliente. Pero si quisieras hacer eso en el lado del servidor y luego hacer exactamente lo mismo en el lado del cliente, para que sea consistente y no tenga que desmontar, volver a montar componentes o volver a renderizarlos innecesariamente, resultó ser bastante complicado. Bueno, eso es exactamente lo que hace useOpaqueIdentifier. Entonces, si realmente voy a los componentes en cuestión y etiquetemos los campos de entrada, podría decir algo como crear un id aquí y por ahora lo crearé fijo. Es el id de cadena. Y con la etiqueta hacemos un for HTML4 para ese id. Y con un signo igual allí, ese campo de entrada tiene un id. Así que ahora están asociados y deberíamos obtener ese comportamiento de enfoque. Entonces, si hago clic en el nombre, el nombre se enfoca. Excepto si hago clic en otro lugar, hago clic en la dirección de correo electrónico, tiene el mismo id por lo que aún establece ese enfoque en el nombre. Entonces, en lugar de esto codificado, ahí es donde queremos usar ese identificador opaco. Entonces, veamos si eso todavía funciona como lo hizo la semana pasada. Así que importo useOpaqueIdentifier con el prefijo inestable y lo llamo sin parámetros ni nada y luego asegurémonos de que esto se actualice. Si hago clic en el nombre, el nombre se enfoca. Si hago clic en el apellido, el apellido se enfoca, el correo electrónico, el título, etc., excepto con la descripción general porque es un área de texto pero podríamos hacer exactamente lo mismo allí. Así que bastante simple. Pero recuerda, esto podría ser renombrado y es posible que ya esté roto en este momento. Espero que si repito los mismos pasos la próxima semana, entonces es casi seguro que estará roto y tendré que usar el hook useID en lugar de useOpaqueIdentifier.

Uso del Hook useOpaqueIdentifier

Short description:

El hook useOpaqueIdentifier en React 18 proporciona un ID opaco, que es una cadena sin ningún significado. Es útil para el renderizado en el servidor y se recomienda su uso en esos casos.

Lo cual, siendo honestos, es un poco complicado de decir. Use identificador opaco, ¡guau, ¿por qué opaco? La razón por la que se llama opaco es porque no debes asignarle ningún significado a ese ID. En realidad, es una cadena pero la cadena en sí no tiene un significado. No deberías analizarla. Es solo un ID. Aún así, es algo pequeño pero útil especialmente si haces renderizado en el servidor. Si no haces renderizado en el servidor y tienes algún tipo de hook para generar IDs como este, simplemente sigue usándolo. No hay necesidad de cambiar inmediatamente. No es como si esto fuera a ser mejor. Pero si estás haciendo renderizado en el servidor entonces este es definitivamente el hook recomendado para usar allí.

Uso del componente Suspense List

Short description:

Podemos usar el componente Suspense List para controlar múltiples límites de suspense y personalizar su visualización, resolución y componentes de fallback. Al especificar el orden de revelación como 'juntos', los componentes de suspense dentro de la lista de suspense se resolverán simultáneamente, lo que resulta en una mejor experiencia de usuario. La opción 'forwards' nos permite decidir cómo manejar los componentes restantes, con el valor 'hidden' ocultándolos. Al agregar una clave al componente, nos aseguramos de que siempre se vuelva a montar, lo que proporciona un comportamiento consistente. La lista de suspense es una adición valiosa para gestionar límites de suspense individuales y controlar su interacción.

Así que el pequeño cambio al input etiquetado y los dos conjuntos de props para el input y la etiqueta y los resultados donde se enfoca. Si quieres ser completo también había, ¿dónde está? Componentes de área de texto etiquetados como área de texto. Podrías hacer exactamente el mismo cambio allí también. Pero, por supuesto, eso es más de lo mismo, así que es opcional.

De acuerdo. Como dije, el siguiente paso es echar un vistazo a cómo podemos orquestar diferentes límites de suspense usando un nuevo componente, el componente Suspense List. Y la lista de suspense es bastante genial. Te permitirá controlar varios límites de suspense diferentes y te dará varias opciones sobre cómo se muestran, cómo se resuelven y qué componente de fallback se debe renderizar o no renderizar. Al igual que con suspense, puedes anidar componentes de lista de suspense, etc. Así que es igual de flexible.

Ahora, vamos a usarlo realmente para solucionar este problema donde si hago clic en usuario, vemos dos spinners y siempre se resuelven en el orden del inferior primero y luego el superior lo que significa que la interfaz de usuario se mueve un poco. Esa película favorita se empuja hacia abajo cuando se resuelven los detalles del usuario. Entonces lo que podemos hacer es aquí, podríamos agregar un componente de lista de suspense. Déjame ponerlo aquí abajo. Y agreguemos el final de la lista de suspense. y ahora mismo, eso en realidad ni siquiera va a marcar la diferencia. Lo agregué pero vemos exactamente el mismo comportamiento que antes. Si no lo configuras, realmente no obtienes nada más. Hay dos propiedades con las que trabajar. Lo más importante es el orden de revelación y eso puede tener tres valores diferentes, hacia atrás, hacia adelante o juntos. No estoy seguro de cuándo usaría hacia atrás pero hacia adelante o juntos son realmente útiles. Así que si digo juntos, obtenemos un comportamiento bastante agradable. Hago clic en el usuario, vemos dos spinners pero ahora en lugar de que la película favorita se resuelva primero y los detalles del usuario se resuelvan después de eso empujando la película favorita hacia abajo, en realidad se resuelven al mismo tiempo. Lo que hace la lista de suspense si especificas juntos, es básicamente esperar hasta que todos los componentes de suspense dentro de la lista de suspense se hayan resuelto y solo cuando todos se hayan resuelto se resolverán realmente. No es como si uno se resolviera antes que el otro. Así que los combina, lo cual es agradable. Obtenemos dos spinners al mismo tiempo. Cuando se completa el último, ambos desaparecen y se renderiza la interfaz de usuario. Lo cual es mucho mejor que antes. Otra opción que podemos hacer es hacia adelante, hacia adelante con una S. En ese caso, podemos decidir qué queremos hacer con el resto, hay una opción de cola y eso toma dos valores, colapsado u oculto. Primero tomaré oculto, que es el que no me gusta mucho, pero ciertamente tiene sus usos. Ahora, si hago clic en el usuario, puedes ver que los detalles del usuario aparecen, pero debajo de eso, nada. Permíteme hacer eso de nuevo. Nada. Pero cuando hago clic en el segundo usuario, en realidad se comporta ligeramente diferente. Ahora vemos spinners de carga y se resuelven al mismo tiempo. Entonces, cuando el componente se monta por primera vez, se comporta de una manera, pero cuando se actualiza realmente y se suspende mientras está montado, se comporta de una manera ligeramente diferente. No estoy seguro si esto es un error o no, pero no es lo que quiero en la interfaz de usuario. Entonces, lo que suelo hacer en casos como este, me aseguro de que siempre esté montado. Y eso es realmente bastante simple. Aquí estoy en el componente que renderiza esa lista y los detalles del usuario seleccionados. Si usas una clave allí, que normalmente se hace en listas de elementos, pero eso funcionará en cualquier componente. Si especificas una clave y esa clave cambia, significa que la instancia del componente, esos detalles del usuario se desmontarán y se montará uno nuevo. Entonces, ahora tengo el comportamiento de que obtenemos nuevos componentes de detalles de usuario con cada usuario. Así que obtenemos el mismo comportamiento. Ves los detalles del usuario aparecer primero, la película siempre después de eso, aunque la película favorita se resuelve más rápido. Pero sin spinners, sin interfaz de usuario de fallback. La falta de interfaz de usuario de fallback se debe a que la cola está oculta. También puedo hacer colapsado. Y esto hará casi lo mismo, excepto que muestra el primer comportamiento de fallback. Entonces, ahora vemos un spinner en los detalles del usuario, y cuando eso se resuelve, muestra la interfaz de usuario, vimos el spinner en las películas favoritas. Entonces, un spinner, otro spinner, lo cual es un poco extraño si consideras que la película favorita en realidad es más rápida, se resuelve antes que el usuario. Se resuelve antes que los detalles del usuario, pero aún así ese spinner aparece. Pero, dado que aparece de arriba a abajo, la interfaz de usuario es mucho más fácil, las cosas no se empujan hacia abajo. Se llena de arriba hacia abajo. Podrías hacer lo mismo con hacia atrás, pero eso no es tan agradable. Ahora vemos un spinner, luego vemos películas favoritas, y luego vemos cómo se empuja hacia abajo con los detalles del usuario. Estoy seguro de que hay buenos casos en los que esto se aplicaría, pero en la mayoría de los casos, no. De hecho, creo que juntos funciona mejor. Y, como puedes ver en el error de compilación, si usas juntos, la opción de cola no se supone que se use. Porque no hay cola, funcionan juntos. Así que dos spinners que se resuelven al mismo tiempo. Y eso es realmente todo lo que hay en la lista de suspense, pero esa es la pieza que faltaba con los límites de suspense individuales donde no puedes controlar cómo funcionan juntos. Ahora, con la lista de suspense, puedes hacerlo, al menos hasta cierto punto, pero las cosas normales que querría hacer, puedo hacerlas. Así que estoy bastante contento. Solo que con algunos valores, la primera vez que se renderiza y se vuelve a renderizar se comporta ligeramente diferente, pero si eso es un error o no, no estoy 100% seguro, pero lo solucioné agregando una clave a ese componente. Entonces se vuelve a montar cada vez y obtengo el mismo comportamiento cada vez. Así que aquí está el cambio que hice. Y lo bueno en este caso, agregué la lista de suspense en el mismo componente que el suspense, pero podría agregar esto en algún lugar más arriba y aún así afectaría a este suspense.

Renderizado Concurrente y Modo

Short description:

React 18 introduce el renderizado concurrente, que permite renderizar en fragmentos y proporciona pequeñas porciones de tiempo para que el tiempo de ejecución de JavaScript ejecute tareas importantes. No es multi-threading, pero coordina el modo concurrente donde React permite que alguien más ejecute entre los fragmentos de renderizado.

No tiene que ser un padre inmediato. Simplemente recorrerá el árbol de componentes nuevamente y React encontrará la primera lista de suspense si está presente y usará esa configuración para trabajar. Así que bastante agradable. Así que esa adición y el resultado. Por favor, agrega el componente de lista de suspense, juega con las diferentes configuraciones, observa cómo se comporta, qué te gusta, qué no te gusta y qué tiene sentido en el tipo de aplicaciones.

De todos modos, lo otro importante que tenemos es el modo concurrente. Ahora, ¿por qué agregó React el modo concurrente? ¿Qué nos ofrece en realidad? Si miramos React 17 y tenemos un montón de componentes renderizando, lo que sucede se ve algo así. A la izquierda tenemos algún estado que cambia y luego, a la derecha, el modelo de objeto de documento en el navegador se actualiza y todos los cuadrados azules son componentes haciendo su renderizado. Y JavaScript siendo lo que es, de un solo hilo, si hay mucho código ejecutándose y ocurre algún evento externo, no puede hacer mucho al respecto excepto encolarlo.

Entonces, con React 17, eso es exactamente lo que sucede. Si los componentes se están renderizando y hay un evento, aquí dice evento de clic, un usuario hace clic, pero eso también podría ser una solicitud Ajax que se completa o un temporizador que se completa algún tipo de evento externo, entonces JavaScript no tiene otra opción que encolarlo hasta que se complete lo que se está ejecutando. Y en el caso de React, eso significa que todos esos renderizados se han ejecutado, el reconciliador entra en acción, compara el DOM virtual, que fue el resultado del renderizado, con el DOM real, ¿hubo alguna actualización allí?, y luego termina y dice, bien, JavaScript, es tu turno, ¿tenías algo más que querías ejecutar? Y luego JavaScript entra y dice, oh, sí, por cierto, tengo este evento de clic, que cambia completamente todo, así que por favor vuelve a ejecutar todo el renderizado. Un poco derrochador, pero JavaScript, al ser un entorno de un solo hilo, no puede hacer otra cosa, no puede ejecutar en paralelo, no sucede.

Ahora, con React 18, con el renderizado concurrente, aún no obtenemos multi-threading, JavaScript no lo tiene, React no puede cambiar eso, pero lo que puede hacer es comenzar a renderizar en fragmentos, y aquí puedes ver diferentes fragmentos, así que tenemos nuestro cambio de estado, y tenemos algunos componentes renderizando, y luego tenemos algunos componentes más renderizando, y luego algunos más, etc., pero entre ellos, aquí y aquí, y las otras pausas, hay pequeñas porciones de tiempo donde React principalmente dice, tiempo de ejecución de JavaScript, ¿por casualidad tienes algo importante que quieres ejecutar?, bueno, ahora es tu momento, adelante, así que no es multi-threading, pero coordina, el modo concurrente, donde básicamente dejas que alguien más intervenga en el proceso.

Estado y Renderizado en React

Short description:

React detecta cambios de estado en el árbol de componentes y determina si continuar con el renderizado o reiniciar. Si ocurre un cambio de estado, React verifica si se llamaron a APIs como useState o setStates, lo cual puede requerir un nuevo dibujo. Para evitar estados de UI inválidos, React proporciona APIs para bibliotecas de gestión de estado para notificarle las actualizaciones de estado y decidir si volver a renderizar el árbol de componentes completo o parcial.

Si no sucede nada, es el mismo proceso, al final, se actualiza el DOM, y se muestra la nueva interfaz de usuario, pero si aparece ese clic, ahora podemos ejecutarlo mucho antes. No tenemos que esperar a que se actualice todo el DOM. Ahora, si eso sucede, el código aquí puede ejecutarse, y puede hacer lo que quiera hacer. Y en el caso de un controlador de eventos o una solicitud AJAX que se completa, por ejemplo, eso podría cambiar potencialmente el estado nuevamente, lo que haría que React diga, bueno, aparentemente lo que estábamos renderizando ha sido invalidado por otro cambio de estado. Ni siquiera nos molestaremos en continuar con esto porque ya está invalidado. Volveremos al inicio y comenzaremos a renderizar todo nuevamente. O, este código del controlador de eventos de clic puede que no cambie ningún estado para React. Entonces React dice, bueno, ejecutamos esta parte de otro código, todo muy útil pero no interesante para nosotros, y continuaremos con el ciclo de renderizado actual y mostraremos los resultados de lo que le sucedió al usuario. Entonces React detecta, ¿se llamó a alguna de nuestras APIs como use state, set states, alguna de estas cosas, que pueden hacer que el árbol de componentes tenga que volver a dibujarse. Si no, continuará, pero si lo hicieron, funcionará. Y ahí es donde entra el desglose del estado. Supongamos que tenemos algunos estados, y déjame tomar mi bolígrafo. Tenemos un objeto de estado y hay un valor aquí. Digamos que tiene el valor uno. Y este componente lo usa, y, ¿por qué no se dibuja? Mi bolígrafo no está ayudando. Así que ese componente se dibuja. Y este componente usa ese mismo estado. Ahora, supongamos que esto actualiza los estados. Dice, bueno, eso no es uno. En realidad, es un dos. Ahora, si React simplemente continuara con su renderizado sin darse cuenta de que el estado ha cambiado, entonces los componentes de la izquierda aquí se renderizarían con uno, y esto se renderizaría con dos para el mismo estado, y entraríamos en algún tipo de UI inválida donde el estado estaba medio actualizado y medio no. Entonces, ahí es donde React ofrece nuevas APIs para desarrolladores de bibliotecas de gestión de estado donde puedes notificar a React, bueno, hicimos algo que causó una actualización de estado, evaluar eso y decidir si necesitamos volver a renderizar el árbol de componentes completo o parcial y no continuar o prevenir este tipo de errores.

Mejorando la capacidad de respuesta con Start Transition

Short description:

Cuando instalamos React 18 y comenzamos a usar create route, comenzamos a utilizar el renderizado concurrente. Sin embargo, la lista de números primos seguía siendo lenta. Por defecto, las aplicaciones se comportan de la misma manera que antes. Para marcar la diferencia, podemos utilizar la API start transition para diferenciar entre trabajos de alta y baja prioridad. Al asignar la parte de los números primos como una prioridad más baja que el valor de entrada del rango, podemos mejorar la capacidad de respuesta. Este cambio, logrado mediante el uso de start transition, permite que la lista de números primos se actualice solo cuando el valor se estabiliza, lo que resulta en una aplicación más receptiva y rápida. La diferencia entre start transition y debounce o throttle es que start transition no se basa en el tiempo, sino en el tiempo de CPU disponible. Este cambio simple tiene un impacto significativo en la interfaz de usuario y la capacidad de respuesta de la aplicación.

Ahora, tan pronto como comenzamos a hacer renderizado concurrente, en realidad, o mejor dicho, cuando instalamos React 18 y comenzamos a usar create route, en realidad comenzamos a utilizar este renderizado, pero realmente no nos ayudó con la lista de números primos. Si voy aquí y voy al rango de 10,000 y arrastro el control deslizante, sigue siendo tan lento como lo era con React 17. La razón es que este mecanismo permite que se inyecten cosas y detecten actualizaciones de estado. Pero por defecto, las aplicaciones se comportarán exactamente de la misma manera. No van a comportarse de manera diferente. Solo habilita la posibilidad. Y hasta que realmente comencemos a usar las API para esto, no veremos ninguna diferencia. Y hay una API, o en realidad dos, pero están empaquetadas de manera diferente. Entonces, en realidad es una debajo del capó, que es start transition, que nos permite comenzar a usarlo. Porque básicamente lo que hace React ahora es diferenciar entre trabajos de alta y baja prioridad. Y por defecto, todo es de alta prioridad. Pero con start transition, podemos decir, bueno, este conjunto de trabajos es en realidad de baja prioridad. Y si hay algo más importante, puedes omitir esto. Simplemente descártalo. No te molestes con eso. Eventualmente no habrá más trabajos importantes. Y cualquier trabajo que estés haciendo en ese start transition se realizará, pero solo las últimas partes, no todo. Entonces, se pueden descartar muchas tareas intermedias. Y si miro esto, si arrastro el mouse, vamos a ir a números un poco más bajos. Si arrastro el mouse en ese control de rango, vemos que estos números primos se vuelven a dibujar y determina si los números son primos o no. Bueno, eso lleva tiempo. Aquí, está bien. Pero con un rango ligeramente mayor, está bien. Todo ese estado, que determina el valor del control deslizante y la lista de números primos están vinculados y se actualizan todos con alta prioridad. Pero tal vez pueda omitir la actualización de la lista de números primos siempre que esté cambiando este control deslizante porque mientras cambie la lista actual que se está representando no es tan importante. Y con start-transition, puedo decir, bueno esta parte, la parte de los números primos es en realidad una prioridad más baja que el valor de esta entrada de rango. Y resulta que hacer eso es bastante simple. Aquí están los componentes reales que son responsables de esa lista. Y puedes ver que hay un rango de primos aquí que establece el número primo máximo a calcular. Y luego hay un bucle aquí para cada número individual. Entonces, donde están los componentes, vamos a cerrar todos estos. Vamos a ir a primos, eso está aquí. Y ahora, cada vez que en ese rango de primos, por lo que ese elemento superior, ese control deslizante, se actualiza, inmediatamente establecerá estos primos máximos, que es un estado normal, que representa este componente, que inmediatamente crea todos esos componentes de verificación de números primos y comienzan a hacer su trabajo. Bueno, no podemos hacer eso. Bueno, hagamos eso un poco más lento o más baja prioridad, debería decir. Start transition. Start transition toma un callback. Entonces ponemos ese código allí y ese es todo el cambio. Entonces, start transition fue importado de React. Parte de React 18. Parte de React 18. Ahora volvemos aquí con los números bajos. Casi el mismo comportamiento. Voy al rango de 10,000, que antes era lento. Hago clic en algún lugar y responde de inmediato. Arrastro, el control deslizante responde de inmediato pero la lista de números primos no se actualiza hasta que me detengo y se estabiliza. O si me muevo más despacio, ocasionalmente tendrá tiempo para actualizarse. Ahí, en realidad se actualizó, pero no realmente. Pero ahora, incluso si voy a números muy grandes hasta un millón, puedo mover este control deslizante y responde rápido y realmente reactivo. Pero la lista de números primos en realidad no se vuelve a calcular hasta que el valor se estabilice. Entonces, ahora realmente estamos utilizando el modo concurrente. Hemos marcado la diferencia. El valor del control deslizante es de alta prioridad. La lista de números primos es de baja prioridad y esa es la parte costosa. Entonces ahora se vuelve mucho más receptivo, mucho más rápido. Y eventualmente, todo será consistente. Y si vuelvo a los números un poco más lentos y muevo el mouse lentamente, ocasionalmente verás que se actualiza. Cuanto más grandes sean los números, más costoso se vuelve. Por lo tanto, menos frecuente se vuelve. Entonces Christina pregunta, ¿qué tan diferente es esto bajo el capó de la función debounce de los inputs? Y esa es una muy buena pregunta porque con React 17 y antes, debounce o throttle serían las opciones a las que recurrir o para resolver un problema de rendimiento como este. Bueno, la gran diferencia entre debounce y throttle por un lado y start transition por otro lado es que debounce y throttle se basan en el tiempo. Podría decir aquí, quiero establecer este valor en debounce después de un retraso de un segundo, lo que básicamente significa que actualiza este valor máximo de números primos si esa función no se ha llamado durante un segundo o si uso throttle, sería el caso de como máximo una vez por segundo, sin importar cuántas veces se llame, lo que significa que si estoy en los números bajos, que son muy receptivos, incluso aquí, si muevo el control deslizante, tomaría un segundo antes de que los números primos reales se actualicen, porque eso es el throttle. Pero con el start transition, no es cuestión de tiempo. Es cuestión de tiempo de CPU disponible. Y aquí hay mucho tiempo disponible. Entonces es realmente receptivo. Aquí, no hay tanto tiempo disponible porque el renderizado lleva más tiempo. Entonces simplemente se ejecuta tan pronto como puede. Entonces esa es una diferencia allí. Un cambio bastante simple, pero tiene un impacto bastante grande en la interfaz de usuario y la capacidad de respuesta de la aplicación.

Introducción a las Transiciones de Inicio

Short description:

Las transiciones de inicio deben utilizarse con prudencia. En algunos casos, como un control deslizante receptivo, tiene sentido utilizarlas. Sin embargo, hay una desventaja en las transiciones de inicio: no proporcionan retroalimentación cuando la lista de números primos se vuelve obsoleta. Exploraremos otra API que aborda este problema.

Normalmente no quieres comenzar a introducir transiciones de inicio en todas partes. Tiene que tener sentido. Como en este caso, donde tengo el control deslizante que necesita ser receptivo, pero esta interfaz de usuario puede quedarse rezagada, eso tiene sentido. En otros casos, puede que no lo tenga. Realmente depende de las circunstancias si tiene sentido. Una desventaja de la transición de inicio que estoy usando ahora es que no hay retroalimentación aquí. La lista de números primos no se actualiza, pero no puedo ver que actualmente esté obsoleta. Estoy usando una lista obsoleta allí. Después de esto, veremos otra API que, bajo el capó, también nos brinda una transición de inicio, pero de una manera ligeramente diferente para solucionar ese problema.

Usando la API useTransition en React 18

Short description:

En esta sección, aprendimos cómo usar la API useTransition en React 18 para iniciar transiciones y obtener el estado actual de las transiciones pendientes. Al usar useTransition, podemos mostrar una interfaz de usuario específica cuando estamos en un estado de transición. Realizamos un cambio simple en el componente PrimeNumbers para usar useTransition en lugar de startTransition, y pasamos la bandera isPending al componente CheckNumber para mostrar un ícono de reloj de arena durante las transiciones. Este cambio mejoró la capacidad de respuesta de la interfaz de usuario y ahora podemos ver el estado pendiente durante las transiciones. Realiza este cambio en tu código. Después de eso, discutiremos las razones por las que tenemos tanto startTransition como useTransition APIs. Ten en cuenta que useTransition no está relacionado con suspense y no implica lanzar promesas.

y, bueno, la lista de números primos que se queda rezagada un poco. Entonces Alexey preguntó, ¿podemos envolver solo nuestro array de números primos? Me refiero a actualizar el estado del componente pero renderizar nuestros números dentro de la transición de inicio. No estoy seguro porque no renderizas dentro de una transición de inicio. Tenemos todo este código aquí que se ejecuta con el renderizado. La API de prueba es un poco diferente. La cosa es que aquí, estos valores se llenan en función del máximo primo. Así que básicamente nos aseguramos de que esto no se actualice. Por lo tanto, la lista no cambia realmente. Sí, solo estaba preguntando porque, si quieres ver el valor real mientras arrastramos este elemento de la interfaz de usuario, si quieres verlo en cada uno, como en cada movimiento, incluso si lo mueves un poco, pero realmente no quieres volver a renderizar todo. Lo mostraré. Permíteme mostrarte cómo funciona el componente PrimeRange. Aquí puedes ver que este es el control deslizante de entrada. Ahí ves en el cambio, realmente llama a los valores en el cambio, que es el controlador externo que acabamos de cambiar aquí. Y tiene su propio conjunto de números primos máximos, que es su propio estado interno aquí, que se utiliza para su propio valor. Así que eso se actualiza de inmediato. El otro controlador se llama, y eso se ejecuta con una prioridad más baja debido a esa transición de inicio. Y por eso este siempre está actualizado y el control deslizante es receptivo. Y ahora este puede quedarse rezagado. También podría haber hecho algo más como tal vez mostrarlos en gris o algo así. Tal vez no renderizarlos. Tal vez lo que sea apropiado en tu interfaz de usuario. Con un cambio bastante trivial. Básicamente, en lugar de importar startTransition, importa useTransition y comienza a usar eso. Así que es bastante simple de hacer. Cambio mínimo y nos brinda algunos beneficios. Podemos ver que estamos en un estado pendiente. Ahora, realiza este cambio. Y después de eso, hablaré brevemente sobre por qué tenemos ambas APIs, porque la primera vez que vi esto, pensamos, si startTransition nos da lo que useTransition ya nos da, ¿por qué necesitamos ambas? Pero resulta que hay buenas razones para tener ambas. Pero hablaremos de eso después de hacer esto. Así que voy a abrir las salas de grupos pequeños durante cinco minutos nuevamente, y veo que hay una pregunta. ¿También es compatible con suspense? Esta es una API no relacionada. Esto no tiene nada que ver con suspense porque aquí no se lanzan promesas. Por lo tanto, en ese sentido, es completamente compatible porque no están relacionados.

Usando StartTransition y UseTransition

Short description:

No es necesario usar suspense. De hecho, no hay componentes de suspense, o en realidad los hay en la raíz, pero no se usan específicamente para esto. StartTransition es más rápido, pero no proporciona comentarios adicionales. Entonces, sí, ambos tienen sus ventajas y desventajas y ambos son útiles. Con UseTransition, puedo mostrar el hecho de que estamos cargando un nuevo usuario aquí dentro de esta lista y tener un poco más de control sobre cómo aparece todo. El clic y la transición aquí están en diferentes límites de suspense ahora, por lo que no cooperan. Pero si entro en los detalles del usuario y eliminamos estos límites de suspense, ahora viven en el mismo límite de suspense. Vemos que se ha desvanecido y ya no vemos ningún spinner, pero estamos dentro de una transición y controlamos exactamente lo que queremos hacer.

No es necesario usar suspense. De hecho, no hay componentes de suspense, o en realidad los hay en la raíz, pero no se usan específicamente para esto.

De acuerdo. Todos han vuelto. Todos han tenido una buena retroalimentación visual ahora desde la transición de inicio. Sí, tengo algo, básicamente se ve mejor, digamos, tenerlo renderizado después de que colocas el punto en algún lugar como izquierda y derecha. Sin embargo, acabo de ver esto, después de un tiempo cuando quieres mover este punto, mueves el punto, luego la tabla con los números se está renderizando o volviendo a renderizar y no puedes mover el punto o el punto se mueve muy, muy lento. No es muy suave. Sí, como. Cuando tienes un data grande. Actualizar y luego ir a 100,000. Por ejemplo. Entonces, al principio. Sí. Ahora es como, sí, pero cuando sueltas el punto ahora, sí y se renderizará. Y ahora cuando intentas moverlo, sí, como puedes ver, se queda atascado en algunos puntos. Parece que cuando React tiene la oportunidad de renderizar, finalmente renderiza esta lista, toma todos los recursos y no libera esos recursos al navegador mientras está renderizando esta lista enorme. Aún considera toda esta lista como una sola parte, como una unidad de trabajo. Sí. Permanece receptivo para mí, pero no es tan receptivo como antes con StarTransition por sí solo. No se queda atascado para mí. Dicho esto, si arrastro ahora, la primera renderización realmente lleva más tiempo. Sí, parece que, porque estamos definiendo el hook en el renderizado, ¿significa que hace el primer render y luego activa la StarTransition? Sí, eso es correcto. Y en realidad, ese es un punto muy bueno para llevarme a la siguiente diapositiva, porque mencioné que iba a hablar sobre por qué tenemos tanto StarTransition como UseTransition. Bueno, como mencionaste, UseTransition es un hook. Y eso significa que solo se puede usar desde un hook o un componente funcional, pero tiene que comenzar con un componente funcional en algún lugar. No puede comenzar desde alguna biblioteca o algo así. Y StarTransition es solo una función que podría comenzar desde cualquier lugar. Podría comenzar desde un componente basado en clase, desde un componente funcional, desde alguna otra biblioteca que conozca React. Entonces, StartTransition es más flexible. La otra cosa, StartTransition inicia la transición y luego termina. UseTransition, llamas a StartTransition que se devuelve de UseTransition, también inicia la transición, pero luego tiene que desencadenar un ciclo de renderizado adicional con esa bandera isPending establecida en true. Por lo tanto, obtienes un renderizado adicional. En este caso, tengo un conjunto bastante grande de números primos aquí. Creo que estoy renderizando 10,000 de ellos. Entonces, la primera vez que lo moví, primero tuvo que renderizar esos mismos 10,000 componentes, nuevamente todos con la bandera isPending en true. Y solo entonces puede dejar de renderizar esos y estamos en la transición. Por lo tanto, es esa primera renderización la que realmente hace que parezca más lento o no solo parezca más lento, es más lento. El hook useTransition es un poco más lento debido al renderizado adicional, pero nos brinda comentarios adicionales y debe usarse desde un componente. StartTransition es más rápido, pero no proporciona comentarios adicionales. Entonces, sí, ambos tienen sus ventajas y desventajas y ambos son útiles. Ahora, resulta que con las transacciones, puedes hacer transacciones de UI más específicas porque en este caso, en realidad necesitamos la retroalimentación porque en esta lista de usuarios, si hago clic en el usuario, veo Loading Spinners, pero tal vez realmente querría mostrar el hecho de que estamos cargando un nuevo usuario aquí dentro de esta lista y tener un poco más de control sobre cómo aparece todo, tal vez no mostrar spinners aquí, sino simplemente desvanecer esto o algo así. Bueno, resulta que con UseTransition, puedo hacer exactamente eso. Entonces vamos a hacer eso. Entonces cerraremos esto. Volveré a mi lista de usuarios y dentro de este clic donde dije seleccionar el usuario, en realidad puedo comenzar a hacer eso dentro de una transacción. Entonces podemos comenzar importando useTransition, como antes. En realidad, eso es solo, lo cerré. Solo copia esa línea, toma ese startTransition aquí. Entonces nuevamente, eso debería ser una flecha alimentada así y una llave más. Y tenemos un startTransition allí. Y ahora puedo hacer algo con esa bandera isPending y tal vez pasar eso aquí. Entonces eso podría mostrarse de manera un poco diferente. Y aún no está en la interfaz. Entonces agreguémoslo allí. Hay un booleano. Recupéralo de las props. Y luego podría hacerlo ligeramente transparente con un estilo dinámico. Opacidad. Si estamos pendientes, lo estableceremos en 0.2 o algo así, y de lo contrario lo dejaremos en el valor predeterminado. Al establecerlo como indefinido, básicamente no lo estamos estableciendo. Ahora, en teoría, eso debería funcionar. En la práctica, aún no lo hace. Permíteme mostrarte qué sucede primero. Nada nuevo. ¿Por qué es eso? Bueno, porque los detalles del usuario en las películas favoritas tienen sus propios límites de suspense, por lo que el clic y la transición aquí están en diferentes límites de suspense ahora, por lo que no cooperan. Pero si entro en los detalles del usuario y eliminamos estos límites de suspense, el límite de suspense allí, ahora viven en el mismo límite de suspense y realmente obtendremos un poco más. Entonces hago clic en el usuario. Vemos que se ha desvanecido y ya no vemos ningún spinner, pero estamos dentro de una transición y controlamos exactamente lo que queremos hacer. Ahora, eso ya se cargó.

Mejorando la Experiencia del Usuario con useTransition

Short description:

Para mejorar la experiencia del usuario, podemos actualizar el estilo activo del usuario inmediatamente al hacer clic, en lugar de esperar a que se complete la transición. Esto se puede lograr duplicando el estado y utilizando el hook useTransition. Al usar useTransition, podemos tener un control total sobre cómo se actualizan los detalles del usuario y evitar que aparezcan spinners. Incluso podemos renderizar indicadores adicionales, como un reloj de arena, condicionalmente para mostrar que el usuario se está cargando. Es importante duplicar el estado y establecer el estado dentro de la transacción para los datos que no nos importan de inmediato, y establecer el estado fuera de la transacción para los datos que nos importan de inmediato. Este cambio puede mejorar significativamente la capacidad de respuesta de la aplicación. Realiza este cambio y nos vemos aquí en cinco minutos.

Permítanme hacer esto de nuevo. Lo único es que si hago clic en el usuario, como hago clic en Spares ahora, el bucle se mantiene resaltado hasta que se complete esa transición. Entonces queremos que el estilo activo no se actualice después de que todo esto se haya cargado, queremos actualizarlo un poco antes. Entonces en realidad tenemos que hacer un poco más de trabajo aquí porque ese estilo activo aquí se hace aquí basado en el usuario seleccionado que estamos estableciendo pero en una prioridad más baja. Entonces en realidad se vuelve a renderizar con ese usuario seleccionado hasta que termine esa transición. Entonces lo que queremos hacer en su lugar es decir, necesitamos duplicar ese estado. Necesitamos el usuario seleccionado o el ID de usuario. Así que copiemos esto. Necesitamos el ID de usuario seleccionado y establecer el ID de usuario seleccionado. El ID de usuario es un número, así que podemos establecerlo por defecto como NaN, no un número. Y luego aquí, podemos comparar el ID del usuario con el ID de usuario seleccionado. Y luego fuera de la transacción, establecemos el ID. Y ese es el ID del usuario. Y en realidad no se necesita ese retorno. No devuelve nada, de todos modos. Ahora el usuario se resalta tan pronto como hago clic en él. Y los detalles se actualizan dentro de la transacción. Y tengo control total sobre cómo se actualizan. Pero fíjense cómo ahora no aparece ningún spinner. Los límites de suspense con sus fallbacks en realidad no inician ningún renderizado de fallback. Porque estoy usando el hook useTransition, básicamente me dejan decidir cómo quiero alimentar al usuario. También puedo moverlo. Puedo dejarlo. Puedo eliminarlo. No importa realmente. No hace nada porque no hay límites de suspense dentro de él. Y básicamente depende completamente de mí. Pero esa es otra capacidad agradable que tengo, que no tenía antes. Entonces, en lugar de usar la lista de suspense, puedo ir aquí y mover la solicitud. Y como pueden ver, eso es lo que hice. Mi lista, para coordinar cómo funcionan los diferentes componentes de suspense, ya sea uno o más, no importa. Todos se enlistan en esta transacción porque todos son parte del mismo límite de suspense. Pero recuerden, tienen que ser parte del mismo límite de suspense. Si vuelvo a poner uno, digamos para la película, entonces eso tendrá su propio comportamiento. Ahora, en realidad esperaba ver un spinner aquí. Pero por alguna razón, no veo el spinner. Interesante. ¿Es por la lista de suspense? Lo dudo, pero vamos a comprobarlo. No, así que supongo que el useTransition anula todo el suspense y la lista de suspense. Siempre y cuando sea parte de él. Si también habilito este suspense, no es parte de él. Ahora obtenemos los spinners. Eliminemos todos esos de nuevo. Así que, en realidad, creo que es un comportamiento bastante bueno. Ahora tienes control total e incluso puedes hacer algún otro renderizado. Tal vez aquí quieras renderizar el hecho de que este usuario se está cargando con otro indicador, algo como... Inserta ese reloj de arena allí y hazlo solo condicionalmente. Si está pendiente, queremos el reloj de arena. De lo contrario, no queremos nada. Así que ahora, si hago clic en renderizarlos completos, eso no era exactamente mi intención, así que agreguemos esta comprobación. Ahora estoy renderizando ese reloj de arena solo para el usuario que estoy cargando actualmente. Lo que quieras. Libertad total porque ahora tienes control total debido a esa bandera isPending, que me gusta mucho. Entonces. Ese mismo cambio que acabo de hacer, pero recuerden, tienen que duplicar el estado, establecer el estado dentro de la transacción para las cosas que no les importan de inmediato y establecer dentro de la transición y establecer el estado fuera de la transición para las cosas que les importan de inmediato. Y recuerden, se vuelven a renderizar y así. Si las cosas son lentas debido a los tiempos de renderizado, entonces aún no obtendrán todos los beneficios. Entonces el componente UserDetails sin el suspense y el suspense Lift. Y el resultado. Por favor, hagan este cambio. Abriré las salas de trabajo y después de eso terminamos. Este es el último ejercicio que vamos a hacer. Así que para concluir y terminar con este masterclass. Pero por favor, hagan este cambio y nos vemos aquí en cinco minutos. Y todos están de vuelta. Así que había una pregunta que me perdí antes de Alexi. ¿Cómo sabe StartTransition si los data están listos y las promesas están listas para resolverse? En realidad no he revisado el código fuente de React, cómo funciona exactamente esto. Pero supongo que busca el límite de suspense más cercano en el padre y verifica su estado. ¿Está suspendido? Entonces sabe que la bandera de expansión debería ser verdadera. Y cuando eso se resuelve, restablecerá esa bandera y los componentes se vuelven a renderizar.

Interacción entre Suspense y Start Transition

Short description:

Suspense y start transition trabajan juntos para manejar la interfaz de usuario de respaldo y comunicarse entre sí. El código fuente de React es complejo y desarrollado por personas talentosas.

Y, por supuesto, esa última parte ya es automática debido a suspense. Es solo que suspense también conoce start transition o al menos el hook use transition porque no muestra su interfaz de respaldo. Así que no estoy seguro de cómo se comunican, pero de alguna manera hay comunicación entre los dos en eso. Suspense debería hacer un poco menos y start transition debería hacer un poco más. Bueno, magia. No estoy seguro de la magia, pero digámoslo así. Si te sumerges en el código fuente de React, es complejo. No es un fragmento de código trivial, en absoluto. Hay personas muy inteligentes trabajando en eso. De todos modos, ese es el final del masterclass. Así que en conclusión, suspense es utilizable hoy con React 17. Las cosas funcionan. Puedes comenzar a buscar datos o buscar componentes de forma perezosa usando suspense. Eso funciona muy bien. Usa límites de error, anida límites de error, anida o paraleliza suspense según sea necesario. La cooperación entre diferentes límites de suspense no funciona. Aún no puede hacer eso en React 17, pero con React 18 sí puedes. Usa suspense list para eso. Usa el hook use transition para eso. Usa start transition directamente o usa el hook use transition para posponer el trabajo de baja prioridad y hacer que las aplicaciones grandes y complejas sean más receptivas. Ni siquiera hemos hablado sobre el renderizado del lado del servidor y todas las cosas que agregaron allí. Eso también es mucho más capaz. Así que espero con ansias el lanzamiento de React 18. Ahora, por supuesto, la pregunta de $10,000 es cuándo se lanzará React 18. Y me temo que no puedo responder eso. No lo sé, tal vez el equipo de React lo sepa, pero sospecho que ni siquiera ellos lo saben. Como de costumbre, probablemente dirán que lo lanzarán cuando esté listo. Lo cual probablemente es la mejor respuesta. No lanzarlo en un horario fijo, lanzarlo cuando esté realmente listo. Ahora, ¿cuándo espero que se lance? Espero que sea antes de fin de año, pero dado que aún no tenemos una versión beta o incluso una versión candidata, todavía estamos en lo que oficialmente es una versión alfa, esperaría que tome al menos otro mes. Entonces, dado que es finales de octubre, no espero ver React 18 antes de diciembre. Así que espero que se lance en algún momento de diciembre. Pero es posible que sea en enero o incluso febrero. El equipo de React se ha tomado su tiempo para asegurarse de que las cosas estén bien antes de lanzarlo, lo cual no puedo culparlos. Demasiado software se lanza según un horario de tiempo en lugar de un horario de calidad. Así que con eso, me gustaría agradecerles por asistir. Espero que haya sido útil. Ya he visto algunos comentarios agradables en el chat, lo aprecio mucho. He terminado todo. ¿Alguna pregunta? Bueno, gracias por asistir. Espero que haya sido útil y disfruten de React 18 cuando se lance, o antes, jugando con él de esta manera.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Top Content
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn
React Advanced Conference 2022React Advanced Conference 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
Top Content
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Top Content
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Top Content
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Top Content
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
Top Content
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!