No puedes usar Hooks condicionalmente... ¿o sí puedes?

Spanish audio is available in the player settings
Rate this content
Bookmark

Es la regla número uno de los hooks: “Solo llama a los hooks en el nivel superior”.


Pero, ¿qué pasaría si te dijera que esta regla no se aplica a todos los hooks? Uno de ellos puede ser usado condicionalmente de manera segura.


Para entender cómo useContext es diferente de otros hooks, y por qué está exento de esta regla principal, necesitamos saber por qué existe esta regla en primer lugar. Construiremos nuestro propio modelo mental del comportamiento de renderizado de react, centrado en cómo react mantiene un seguimiento de los datos en tiempo de ejecución: props, estados, refs... y valores de contexto.

28 min
02 Jun, 2023

Video Summary and Transcription

La charla discute el uso del hook Use en React y su capacidad para ser usado condicionalmente. Explica el concepto del árbol de fibra y cómo se almacenan los valores de los hooks en la memoria. La charla también profundiza en el uso condicional de useContext y cómo difiere de useState. Explora el proceso de actualización de los valores de contexto y la optimización del renderizado de contexto. Se enfatiza el papel del proveedor en la gestión de los valores de contexto y el renderizado.

Available in English

1. Introducción al Use Hook

Short description:

Hace unos meses, el equipo central de React hizo una propuesta para preguntar a la comunidad su opinión sobre la idea de agregar un nuevo hook, el Use hook. Use tendría una habilidad especial. Seríamos capaces de usarlo condicionalmente. En la propuesta, luego aprendimos que use no solo estaría obstaculizando las promesas, sino también otras cosas, como los valores de contexto.

Hola a todos, soy Charlotte, y hoy vamos a desafiar las leyes de los hooks juntos. Hace unos meses, el equipo central de React hizo una propuesta para preguntar a la community su opinión sobre la idea de agregar un nuevo hook, el Use hook. Una versión exclusiva de React de Await que desempaqueta promesas, permitiéndonos obtener datos sincrónicos data y usarlos directamente en nuestros componentes. No voy a detenerme en este hook hoy, pero hay una cosa sobre este hook que me interesa. Use tendría una habilidad especial. Seríamos capaces de usarlo condicionalmente. ¿Qué? ¿Cómo es eso posible? Solo hay dos reglas con respecto a los hooks. Regla número uno, solo llame a los hooks desde las funciones de React, por lo tanto, componentes de función y otros hooks, y regla número dos, no llame a los hooks condicionalmente. Solo dos reglas, ¿y este hook estaría exento de la mitad de ellas? Empeora. En la propuesta, luego aprendimos que use no solo estaría obstaculizando las promesas, sino también otras cosas, como los valores de contexto. Seríamos capaces de leer los valores de contexto con use, al igual que lo hacemos con use context.

2. Entendiendo el Uso Condicional de Use Context

Short description:

Para entender por qué use context puede ser utilizado condicionalmente, primero necesitaremos entender por qué otros hooks no pueden. Cuando construimos nuestra aplicación por primera vez, React crea un árbol de fibras para hacer un seguimiento de nuestros componentes. Cada componente está representado por un objeto de fibra que contiene información sobre el componente. El árbol de fibras ayuda a React a determinar qué elementos deben ser renderizados y actualizados en el DOM. Cuando instanciamos un componente de React, se añade una nueva fibra al árbol. La fibra contiene el tipo de componente, sus props y su posición en el árbol.

Así que déjame entender esto correctamente. Esto significa que seríamos capaces de leer los valores del contexto condicionalmente, y de hecho, hemos aprendido en este tweet de Andrew Clarke que ya podemos. Ya podemos llamar a use context condicionalmente. ¿Pero por qué? ¿Por qué use context puede ser utilizado condicionalmente, mientras que otros hooks no pueden? Esa es la pregunta que vamos a intentar responder hoy.

Para entender por qué use context puede ser utilizado condicionalmente, primero necesitaremos entender por qué otros hooks no pueden. Y para entender esto, necesitaremos entender cómo funcionan los hooks. ¿Dónde se almacena el data de un hook? ¿Cómo hace React para hacer un seguimiento de nuestros data a través del tiempo y del renderizado? Para entender la diferencia de use context, primero necesitaremos entender React. Así que comencemos con esta primera pregunta.

¿Dónde se almacena el data de nuestro hook? ¿Dónde se almacena el data de nuestro componente? Cuando construimos nuestra aplicación por primera vez, React va a construir este árbol virtual hecho de nuestros componentes de React. Este árbol se llama el árbol de fibras. El árbol de fibras hace un seguimiento de los componentes de React que componen nuestra aplicación. Y a partir de este árbol, React va a inyectar nuestros elementos HTML en el DOM para mostrar nuestra aplicación en la pantalla. El árbol de fibras mantiene en memoria a través del tiempo y re-renderiza información sobre nuestros componentes, sus data, sus props y sus estados. De esta manera, cuando ocurre el re-renderizado, React sabe qué elementos deberían haber cambiado, cuáles deberían ser renderizados y qué información debería ser actualizada en el DOM.

Así que la primera vez que construimos nuestra aplicación, React crea este árbol de fibras. Cada vez que instanciamos un componente de React, React añade un nodo al árbol. Y tal nodo se llama una fibra. Echemos un vistazo a uno de ellos. Echemos un vistazo a una fibra en este componente de saludos. Cuando instanciamos saludos, estamos utilizando esta sintaxis JSX, y JSX es en realidad sólo azúcar sintáctica y es equivalente a la llamada de esta función JSX, o crear elemento hasta React 17. Y esta función JSX, cuando se ejecuta, creará, añadiremos, una nueva fibra en el árbol. Así que cuando instancias un componente con esta sintaxis JSX, en realidad añades un nodo en el árbol. Creas una nueva fibra.

Ahora, ¿cómo es realmente una fibra? Bueno, una fibra es simplemente un objeto que contiene información sobre un componente. Así que si miramos esta fibra de saludos, tenemos su tipo, tenemos sus props, los data de las props, se mantienen en memoria dentro de cada fibra, junto con un montón de otros estados y banderas para que React pueda hacer un seguimiento, y finalmente, tenemos su posición dentro del árbol de fibras. Hablando del árbol de fibras, veamos cómo se construye. Veamos qué pasa en el primer renderizado cuando se construye nuestro árbol de fibras. Vamos a recorrer nuestro code, y cada vez que instanciamos un componente de React con esta sintaxis JSX, React va a añadir una fibra al árbol.

Así que primero, tenemos este componente de aplicación que tiene el nombre de usuario en este estado que pasa a este componente de saludos, que lo muestra en un párrafo, y finalmente, tenemos este botón que podemos pulsar para cambiar nuestro nombre de usuario. Y aquí vamos.

3. Entendiendo el Árbol de Fibras y los Hooks

Short description:

Hemos construido nuestro árbol de fibras e inyectado nuestros componentes en el DOM. Los valores de los hooks se almacenan en la memoria dentro de cada fibra individual como una lista enlazada. El componente de función no retiene datos; la fibra sí. Cuando se ejecuta la aplicación, los valores almacenados en la fibra se pasan a la función.

Hemos construido nuestro árbol de fibras. ¿Y ahora qué? Este árbol todavía es virtual. Aún no hemos mostrado nada en el DOM. Así que lo que React va a hacer es que va a inyectar nuestros componentes en el DOM, pero no todos ellos. Algunos de estos componentes son puras funciones de React. Este componente de saludos, por ejemplo, es un componente puro de React. No existe en el DOM. No es un elemento HTML. Así que lo que React va a hacer es que va a recorrer nuestro árbol de fibras y cada vez que encuentra un elemento HTML, lo va a inyectar en el DOM. Así que nuestro párrafo y nuestro botón. Y ahora nuestra aplicación está en vivo en la pantalla.

Así que nuestros componentes data, nuestras props, se mantienen en la memoria dentro de cada fibra. Ahora, ¿qué pasa con los hooks? Estamos aquí para hablar de hooks, ¿verdad? Así que vamos a añadir un segundo estado aquí. ¿Dónde se almacenan estos dos valores? Bueno, lo has adivinado. Los valores de los hooks se mantienen en la memoria dentro de cada fibra individual también, pero no de cualquier manera. Los valores de los hooks se almacenan dentro de una lista enlazada, donde cada valor apunta hacia el siguiente. Estos valores son luego leídos por los hooks en el orden en que son llamados. Una cosa que tienes que entender aquí es que este componente de función, app, es solo una función. No retiene data. UseState no retiene data. La fibra sí. Cuando ejecutas la aplicación, ejecutas esta función y le pasas los valores que se almacenaron en la memoria dentro de la fibra. Así que vamos a ejecutar la aplicación por primera vez. Construyamos nuestra fibra. Ejecutamos la aplicación. Vamos a estar escribiendo esto. Este useState estará escribiendo ese valor predeterminado en la fibra en el orden en que son llamados. Así que primero, tendremos nombre, que va a estar escribiendo en el primer elemento de la lista enlazada ya que está vacía hasta ahora, Rachel. Luego tenemos edad, que va a estar escribiendo en el elemento actual de la lista enlazada, .next. Así que el segundo, 29.

4. Entendiendo Hooks y Uso Condicional

Short description:

¿Qué sucede después del renderizado? ¿Puedes ver en este esquema por qué no puedes llamar a los Hooks de manera condicional? Intentemos llamar a este estado de nombre de manera condicional basándonos en este primer valor booleano. Tenemos este error que probablemente ya has encontrado en tu vida como desarrollador de React. Los Hooks dependen del orden en que se llaman. Todos ellos son interdependientes en sus listas enlazadas. Por eso no puedes usarlos de manera condicional.

¿Qué sucede después del renderizado? ¿Qué sucede si hacemos clic en este botón aquí y cambiamos nuestro primer estado, nuestro nombre de usuario? Vamos a renderizar. Vamos a ejecutar la aplicación y pasarle los valores que se guardaron en la memoria dentro de la fibra. Así que primero, el nombre va a leer el primer elemento de la lista enlazada y la edad el segundo. ¿Puedes ver en este esquema por qué no puedes llamar a los Hooks de manera condicional? Los Hooks dependen del orden en que se llaman. Así que si en el próximo renderizado añades o quitas un hook, cambias el orden y los data que obtienes no son los correctos.

Intentémoslo. Intentemos llamar a este estado de nombre de manera condicional basándonos en este primer valor booleano que es originalmente igual a falso. Rendericemos la aplicación por primera vez. Así que primero tenemos shuname que va a escribir falso en el primer elemento de la lista enlazada. Y no pasamos esta condición, así que pasamos a la edad que va a escribir 29. ¿Qué sucede si hacemos clic en este botón aquí y cambiamos nuestro primer booleano a verdadero? Renderizaremos la aplicación y le pasaremos estos dos valores. Así que primero, shuname va a leer verdadero en el primer elemento de la lista enlazada. Luego, esta vez pasamos esta condición, así que tenemos nombre que va a leer 29. Así que sí, el nombre va a ser 29 y luego tenemos edad que no puede encontrar su valor en ninguna parte y nos saca. Tenemos este error que probablemente ya has encontrado en tu vida como desarrollador de React. Los Hooks dependen del orden en que se llaman. Todos ellos son interdependientes en sus listas enlazadas. Por eso no puedes usarlos de manera condicional.

5. Entendiendo el Uso de useContext

Short description:

¿Y qué pasa con useContext entonces? ¿Por qué useContext puede usarse condicionalmente? Vamos a retorcer un poco nuestro ejemplo y usar proporciona nuestro nombre de usuario en este valor de contexto. La respuesta se encuentra en nuestro árbol de fibra. Así que vamos a construirlo. Primero tenemos estos objetos de contexto, luego tenemos la aplicación que todavía tiene el nombre de usuario en este estado que pasa esta vez en props a este proveedor de contexto. Debajo del proveedor tenemos saludos que ahora es un consumidor de contexto. Lee el valor del contexto del valor del nombre de usuario del contexto y lo pasa a este párrafo. Y finalmente, terminamos con este botón en el que podemos hacer clic para cambiar nuestro valor de contexto.

¿Y qué pasa con useContext entonces? ¿Por qué useContext puede usarse condicionalmente? Vamos a retorcer un poco nuestro ejemplo y usar proporciona nuestro nombre de usuario en este valor de contexto. La respuesta se encuentra en nuestro árbol de fibra. Así que vamos a construirlo. Primero tenemos estos objetos de contexto, luego tenemos la aplicación que todavía tiene el nombre de usuario en este estado que pasa esta vez en props a este proveedor de contexto. Debajo del proveedor tenemos saludos que ahora es un consumidor de contexto. Lee el valor del contexto del valor del nombre de usuario del contexto y lo pasa a este párrafo. Y finalmente, terminamos con este botón en el que podemos hacer clic para cambiar nuestro valor de contexto.

6. Entendiendo el Uso Condicional de useContext

Short description:

¿Puedes ver en este esquema por qué useContext puede usarse condicionalmente? useContext lee y almacena su valor dentro de un objeto de contexto ubicado fuera del árbol, sin relación con otros hooks. Al llamar a useContext, el objeto de contexto se pasa como argumento, permitiendo el acceso directo al valor. useState, por otro lado, depende del orden para determinar su valor, ya que no hay identificadores para diferenciar múltiples instancias. Esta distinción permite el uso condicional de useContext.

¿Puedes ver en este esquema por qué useContext puede usarse condicionalmente? Vamos a agregar un segundo estado aquí. Los valores de los Hooks como useState o useEffect leen y almacenan su valor dentro de la lista enlazada donde todos los Hooks son interdependientes y donde otros importan. useContext, por otro lado, lee y almacena su valor dentro de un objeto de contexto que está ubicado fuera del árbol, fuera de la lista enlazada. useContext no está relacionado con otros hooks de la manera en que lo está useState. Así que puedes llamarlo condicionalmente todo lo que quieras. Simplemente no afectará a otros hooks.

Y eso es algo que también puedes ver en el code. Echa un vistazo más de cerca al code. Verás que cuando llamas a useContext, le estás pasando en argumentos, el objeto de contexto. Le estás diciendo, ve a verificar tu valor justo aquí en este mismo objeto. Está codificado. useState, por otro lado, no recibe ninguna variable clave codificada para encontrar su valor. Todo lo que recibe es la lista de valores de todos los hooks de la fibra. Y este useState es igual que este otro. No hay un identificador para diferenciarlos. Entonces, ¿cómo sabe cuál de estos valores le pertenece? Depende del orden. Esa es la implementación que se decidió. Por eso es por lo que useContext puede usarse condicionalmente. Por eso es por lo que useContext es diferente.

7. Entendiendo la Actualización de los Valores de Contexto

Short description:

Para entender cómo se actualiza un valor de contexto, necesitamos entender cómo se actualiza cualquier valor regular. Cuando cambiamos el valor de contexto, React calcula una nueva versión del árbol de fibra que corresponde al cambio. Compara este nuevo árbol con el anterior y aplica las diferencias al DOM. Sin embargo, sólo se renderizan los componentes que pueden haber cambiado, no todos los componentes. Este proceso de cálculo implica duplicar el árbol de fibra, actualizarlo para reflejar el cambio, marcar la fibra que contiene el estado cambiado, y recorrer el árbol para decidir qué componentes renderizar.

Pero parece que todavía falta algo. ¿Cómo funciona esto exactamente, verdad? El valor del contexto se encuentra dentro de este objeto. Pero si este objeto se encuentra fuera del árbol, ¿cómo se actualiza? ¿Y cuál es realmente el papel de este proveedor aquí? Para que nuestra demostración sea completa, me gustaría profundizar un poco más si les parece bien, y realmente entender cómo se actualiza un valor de contexto, cómo funciona un valor de contexto por debajo.

Bueno, chicos, los próximos minutos van a ser bastante intensos. Para entender cómo se actualiza un valor de contexto, primero necesitaremos entender cómo se actualiza cualquier valor regular. Así que vamos a tener un poco de teoría aquí sobre el comportamiento de renderizado de React. Así que tengan paciencia conmigo. Bien, ¿cómo se actualiza un valor de contexto? Hagamos clic en nuestro botón aquí y cambiemos nuestro valor de contexto. Veamos qué pasa. Vamos a volver a renderizar. Activamos un set state. Lo que va a pasar es que vamos a calcular una nueva versión de nuestro árbol de fibra que corresponde al cambio que hemos hecho a nuestro nuevo estado, nuestro nuevo renderizado. Una vez que se ha hecho, React va a comparar este nuevo árbol con el del orden anterior y aplicará las diferencias al DOM. Pero cuando calculamos este nuevo árbol de fibra, no renderizamos realmente todos los componentes de nuestra aplicación que podrían ser ineficientes, sólo los que pueden haber cambiado. Veamos cómo va este proceso de cálculo paso a paso.

Así que hacemos clic en este botón aquí para cambiar nuestro valor de contexto. Vamos a cambiar para activar un set state. Vamos a renderizar. En este punto, suceden varias cosas. Primero, como dijimos, vamos a duplicar nuestro árbol de fibra. Vamos a actualizar este nuevo árbol de fibra para que corresponda al cambio que hemos hecho. Pero hasta ahora, es lo mismo. Es sólo una copia. Segunda cosa, vamos a marcar la fibra que contiene el estado que acaba de cambiar como necesitada de renderizar. Así que a este componente de aplicación, esta fibra de aplicación, vamos a añadirle esta pequeña bandera de renderizado. Y finalmente, vamos a recorrer nuestro árbol. Vamos a visitar cada fibra. Y para cada una de ellas, nos vamos a preguntar, ¿deberíamos renderizar estos componentes? Si lo hacemos, renderizaremos. De lo contrario, nos retiramos. Esperamos, nos vamos.

8. Renderizando el Componente App

Short description:

Comenzamos en la parte superior de nuestro árbol con la primera fibra de la aplicación. La aplicación está marcada para un nuevo renderizado, así que la volvemos a renderizar.

No renderizamos. Y comenzamos en la parte superior de nuestro árbol con la primera fibra de la aplicación. Así que vamos a usar esta pequeña bandera de trabajo en progreso solo para tener en cuenta qué fibra estamos visitando actualmente. Así que la aplicación. ¿Deberíamos renderizar la aplicación? Hay dos criterios para que un componente sea renderizado. Y si cumple con alguno de ellos, renderizamos este componente. El primero es estar marcado para un nuevo renderizado. Y la aplicación fue marcada para un nuevo renderizado. Así que está bien. Volvemos a renderizar la aplicación. Añadamos algo de color en este esquema. Pongamos en azul las fibras que fueron renderizadas de nuevo solo para tenerlo en cuenta. Así que hemos vuelto a renderizar la aplicación.

9. Ejecución de Componentes de Función

Short description:

Ejecutar componentes de función significa ejecutar la aplicación y pasar los valores almacenados en la fibra. Al renderizar la aplicación, se crean nuevas fibras para todos los componentes instanciados con la sintaxis JSX.

¿Qué significa esto? Significa ejecutar sus componentes de función. Así que ejecutamos la aplicación y le pasamos los valores que se guardaron en la memoria dentro de la fibra. Así que en primer lugar, vamos a leer el último valor de nombre de usuario que acaba de cambiar. Y luego vamos a través de todo este JSX. Y aquí mira. Mira este componente de saludos, estamos utilizando la sintaxis JSX aquí. Y recuerda que JSX es equivalente a la llamada de esta función JSX que crea fibras. Así que lo que esto significa es que en nuestro nuevo árbol para estos componentes de saludos, vamos a descartar completamente la fibra anterior y añadir una completamente nueva. Este es un nuevo objeto. Y algo, sí, pongámoslo en naranja. Las nuevas fibras están en naranja sólo para tenerlo en cuenta. Algo que debes notar aquí y que será útil más tarde es que mientras estamos creando una nueva fibra para los saludos, también estamos creando un nuevo objeto de props. Este es un objeto completamente nuevo. Será útil más tarde. Así que mientras estamos renderizando la aplicación, vamos a crear nuevas fibras para todos los componentes que instancie con esta sintaxis JSX.

10. Renderizando el Proveedor de Contexto

Short description:

Renderizamos el proveedor, que es un proveedor de contexto y actualiza el valor del objeto de contexto basado en sus props.

Entonces, nuestro proveedor también, al que le estamos pasando el último valor de nombre de usuario en props y nuestro y hemos terminado con la aplicación. Así que podemos pasar a la siguiente fibra, nuestro proveedor de contexto. ¿Deberíamos renderizar el proveedor? Bueno, no fue marcado para renderizar pero hay un segundo criterio para ser renderizado y es basado en el valor de las props. Vamos a comparar estos objetos de props, el objeto de props de la fibra del nuevo árbol con el del árbol anterior. Vamos a comparar estos dos objetos a través de la igualdad superficial y si son iguales, no renderizamos, de lo contrario sí. Y en nuestro caso, son diferentes. Así que renderizamos el proveedor. Así que ejecutamos este componente de función pero eso no es todo. Verás, este componente es algo especial. No es solo un componente de función regular. Es un proveedor de contexto. Entonces, hace otras cosas también, como actualizar el valor del objeto de contexto, basado en el valor que obtuvo de sus props. Así que el proveedor actualiza el valor del objeto de contexto y hemos terminado con el proveedor. Así que podemos pasar a la siguiente fibra.

11. Renderizando Componentes y el Árbol de Fibra

Short description:

Cuando creamos una nueva fibra para saludos, creamos un nuevo objeto para sus props. Aunque los objetos pueden parecer similares, tienen diferentes referencias. La igualdad superficial de JavaScript considera que los objetos vacíos no son iguales. Por lo tanto, renderizamos saludos. Luego ejecutamos los componentes de función, leemos el último valor de nombre de usuario del objeto de contexto y creamos una nueva fibra para el párrafo. El párrafo y el botón también se renderizan. React compara el nuevo árbol con el anterior y aplica las diferencias al DOM. Es importante destacar que en realidad solo hay un árbol en la realidad, pero es más fácil pensar en él como dos árboles. El árbol de fibra, no el código, es la fuente de verdad para saber qué componentes pueden haber cambiado y deben renderizarse.

Saludos, ¿deberíamos renderizar saludos? Bueno, no fue como para renderizar pero, ¿han cambiado sus props? Bueno, en realidad sí, lo han hecho. Lo sé, dos objetos vacíos, parecen muy similares pero este es un objeto diferente. Así que cuando creamos una nueva fibra para saludos, también creamos un nuevo objeto para estas props también. Tiene la misma, no, diferente referencia, si quieres. Y en JavaScript, a través de la igualdad superficial, recuerda que objeto vacío igual a objeto vacío es falso a través de la igualdad superficial. Así que en nuestro caso, estos dos objetos son diferentes y sí renderizamos saludos.

Así que ejecutamos estos componentes de función. Leemos el último valor de nombre de usuario del objeto de contexto y creamos una nueva fibra para el párrafo al que pasamos el nuevo valor de nombre de usuario. Y hemos terminado con saludos. Así que pasamos al párrafo, que se renderiza, porque sus props han cambiado, igual que los saludos. Y pasamos al botón, que también se renderiza. Y hemos terminado de construir nuestro árbol. Ahora, React va a comparar este nuevo árbol con el del orden anterior y aplicar las diferencias al DOM. Y ahora hemos terminado. Esto fue algo mecánico. Así que vamos a dar un paso atrás de esto. Hay una o dos cosas que me gustaría discutir juntos. Primero sobre React y luego hablaremos sobre el contexto.

Sobre React, una pequeña advertencia. No es del todo cierto que tengamos estos dos árboles. En realidad, solo hay uno. Y cada fibra se aferra a toda su historia de estados. Pero simplemente me resulta más fácil pensar en él como dos árboles. Y quiero decir, es mi modelo mental. Así que si quiero tener dos árboles, tendré dos árboles. Segunda cosa aún sobre React. Hay un malentendido que tenía sobre React que quería compartir con ustedes. Solía pensar que la fuente de verdad, para saber qué componentes pueden haber cambiado y cuál debería ser renderizado era el code. Pero no lo es. El árbol de fibra lo es.

12. Entendiendo la Representación y el Uso del Contexto

Short description:

Cuando renderizamos la aplicación, se crea una nueva fibra para saludos, y se recorre todo el árbol. React renderiza saludos cuando detecta que sus props han cambiado. En el uso real, los primeros componentes debajo del proveedor rara vez son consumidores de contexto. Se pueden agregar componentes adicionales entre el proveedor y el primer consumidor de contexto. Cuando se cambia el valor del contexto, todos los componentes en la cascada se representan.

Solía pensar que cuando renderizábamos la aplicación, el hecho de que estemos llamando a este componente de saludos de esta manera significaba que lo estaríamos ejecutando de inmediato. Pero eso no es lo que está sucediendo. Lo que está sucediendo es que cuando renderizamos la aplicación, cuando ejecutamos esta línea, creamos una nueva fibra para saludos. Y luego estamos recorriendo todo el árbol. Y más tarde, cuando estamos visitando saludos, React está diciendo, oh, sus props han cambiado. Deberíamos renderizar eso. Y solo entonces ejecutamos estas líneas. La fuente de verdad es el árbol de fibra.

Ahora en tu vida diaria, sé que no estarás dibujando árboles de fibra. Así que lo que puedes recordar, lo que puedes llevar de esto es que cuando estás debajo, cuando el componente se renderiza, todas las instancias de los componentes también se renderizarán. Ahora sobre los contextos. Así es como funcionan los contextos. Cambiamos el valor del estado que se refiere a los estados establecidos. El proveedor se renderiza. Actualiza el valor del contexto, lo siento, problemas de animation. Actualiza el último contexto, los valores del contexto, el valor del contexto del objeto de contexto. Y luego todos estos componentes se van a renderizar en cascada y este componente de gradiente va a leer el último valor de contexto del objeto de contexto. Pero en realidad aún no hemos terminado. Esto no representa realmente un uso real del contexto. En la vida real, los primeros componentes ubicados justo debajo del proveedor casi nunca son un consumidor de contexto.

En la vida real, se parece más a esto. Agregamos algunos componentes extra entre el proveedor y el primer consumidor de contexto. Ahora en este caso, si echamos un vistazo a estos componentes A y B, ¿crees que ellos también se renderizarán si cambiamos nuestro valor de contexto si hacemos clic en este botón? Bueno, en realidad sí. Si hacemos clic en este botón aquí, vamos a renderizar la aplicación. Entonces la aplicación, cuando se ejecuta, creará una nueva fibra para A. Así que A se renderizará. Entonces creará una nueva fibra para B. Así que B se renderizará y así sucesivamente. Todos estos componentes se renderizan en cascada. Pero quiero decir que eso es demasiado malo.

13. Optimizando la Representación del Contexto

Short description:

Queremos evitar la representación de componentes que no dependen del contexto cuando el valor del contexto cambia. Una forma de lograr esto es memorizando el primer componente debajo del proveedor. Otra forma es extraer el proveedor en su propio componente personalizado y pasar el resto del árbol como prop de los hijos. Al hacer esto, cuando el valor del contexto cambia y se representa el proveedor, los componentes pasados como hijos no se volverán a representar. Vamos a demostrar esto cambiando el valor del contexto y observando el proceso de representación. Duplicamos el árbol de fibra, marcamos el componente que contiene el estado, y recorremos el árbol. No volvemos a representar la aplicación porque sus props no han cambiado. Esta optimización nos permite evitar representaciones innecesarias y mejorar el rendimiento.

Hemos representado porque cambiamos el valor del contexto pero A y B no dependen del contexto. No han cambiado. No deberíamos representarlos. Eso es demasiado malo. Y quiero decir que cuando llamas a useContext, estás tratando de llamarlo lo más bajo posible en tu árbol, lo más cerca posible de donde realmente lo necesitas. Así que si podemos, sería bastante bueno evitar la representación de todos los componentes ubicados entre el proveedor y el consumidor de contexto.

¿Entonces cómo podemos lograr esto? ¿Cómo podemos no volver a representar A y B si cambiamos nuestro valor de contexto? Bueno, una cosa que ya había escuchado antes es memorizar el primer componente ubicado justo debajo del proveedor. De esta manera, memorizamos este componente. De esta manera, detenemos la propagación de la representación. Esto debería funcionar pero en realidad, hay otra forma de lograr esto, que está incluso más cerca de un uso real del contexto. ¿Puedes adivinar cuál es? Es extraer tu proveedor en su propio componente personalizado y pasar el resto de el árbol como prop de los hijos. De esta manera, cuando cambiamos nuestro valor de contexto y se representa el proveedor de autenticación, cuando se representa el proveedor de autenticación, este componente A que se pasa como prop de los hijos no se representará y detendremos la propagación de la representación.

Vamos a hacer la demostración muy rápido. Vamos a hacer clic en este botón aquí y cambiar nuestro valor de contexto. Duplicamos nuestro árbol de fibra, vamos a marcar el componente que contiene el estado como necesitado para representar. Así que esta vez no es la aplicación, son estos componentes personalizados del proveedor de autenticación. Así que marcamos el proveedor de autenticación y comenzamos a recorrer nuestro árbol. Comenzamos con la aplicación, ¿deberíamos representar la aplicación? Bueno, no fue marcada para representar pero ¿han cambiado sus props? Bueno, en realidad no. Esta vez, este objeto de props es el mismo que este. Cuando duplicamos nuestro árbol, este árbol es la copia superficial de este. Es una copia directa de este, así que este objeto de props es una copia directa de este. Mantienen la misma referencia si se puede. En JavaScript, esta vez a través de la igualdad superficial, estos dos objetos son iguales. Así que no volvemos a representar la aplicación. ¿Te diste cuenta? Es el primer componente en los últimos 10 minutos que en realidad no representamos. Se siente genial. Muy bien. Pasemos al proveedor. Se representa ya que fue marcado, así que lo ejecutamos. Obtenemos el último valor de nombre de usuario y creamos nuevas fibras para el proveedor y el botón.

14. Entendiendo el Papel del Proveedor

Short description:

Pero aquí, children es solo una prop, es solo una variable. El proveedor se encargará de asegurar que los consumidores de contexto se rendericen. AuthProvider, nuestro proveedor de contexto, marcará las lecturas como necesarias para renderizar. Extraer el proveedor en sus propios componentes personalizados no solo conduce a una mejor separación de responsabilidades, sino que también asegura que todos los componentes ubicados entre el proveedor y el primer consumidor de contexto no se rendericen. El papel del proveedor es absolutamente crucial. Va a actualizar tanto el valor del objeto de contexto dentro de los objetos de contexto como asegurar que los consumidores se rendericen.

Pero, ¿qué pasa con esta prop children? ¿Qué pasa con este componente A que se pasó como prop children? ¿Deberíamos crear una nueva fibra para ello? Bueno, en realidad, no. La razón por la que estamos creando una nueva fibra para un botón es debido a esta sintaxis JSX que es equivalente a la función JSX que crea fibras. Pero aquí, children es solo una prop, es solo una variable. No hay JSX aquí, por lo que no hay razón para crear una nueva fibra para A. Así que no hay nueva fibra de A y hemos terminado con el proveedor. Podemos pasar al proveedor de contexto real, que se renderiza ya que sus props han cambiado. Actualiza el valor del contexto y pasamos a A, que tampoco se vuelve a renderizar. Ves que, al igual que para la aplicación, este objeto de props es el mismo que este, por lo que no renderizamos A, ni B, ni los saludos. Pero ahora tenemos un problema.

Saludos es un consumidor de contexto. Queremos que se renderice para leer el último valor de nombre de usuario, de lo contrario nuestra aplicación no tiene sentido. Queremos que los saludos se rendericen y en realidad lo harán. El proveedor se encargará de ello. Hay algo que no te conté. Volvamos a cuando estamos visitando al proveedor. Dijimos que cuando el proveedor se renderizaba, actualizaría el valor del objeto de contexto, pero eso no es todo lo que hace. También se va a asegurar de que los consumidores de contexto se rendericen. Va a recorrer todas las fibras que están ubicadas debajo de él y marcará a los consumidores de contexto como necesarios para renderizar. Tiene esta información dentro de las fibras porque cuando un componente se renderiza, si utiliza un contexto, useContext va a escribir esta dependencia hacia el contexto dentro de la fibra. Así que AuthProvider, nuestro proveedor de contexto, va a marcar las lecturas como necesarias para renderizar. De esta manera, incluso si un componente se memoriza en el medio y la propagación de renderizado se detiene, asegura que los consumidores se rendericen. Y puedes ver que no mentí. Este componente A no se renderizó cuando se renderizó AuthProvider porque se pasó como esta prop children. Entonces, en realidad, extraer el proveedor en sus propios componentes personalizados no solo conduce a una mejor separación de responsabilidades. También asegura que todos los componentes ubicados entre el proveedor y el primer consumidor de contexto no se rendericen.

Y esto es en realidad, oh sí, lo siento, una última cosa. Una vez que se renderiza el primer consumidor de contexto, por supuesto, si agregas algunos componentes extra debajo de él, todos ellos también se van a renderizar. Y así es como funciona el contexto. Y puedes ver que el papel del proveedor es absolutamente crucial. Va a actualizar tanto el valor del objeto de contexto dentro de los objetos de contexto y asegurar que los consumidores se rendericen para que puedan leer el último valor de contexto de los objetos de contexto.

15. Uso Condicional de useContext en Hooks

Short description:

Con esta imagen completa de cómo funciona el contexto, podemos confirmar que useContext puede usarse condicionalmente sin interferir con otros hooks. Sin embargo, se aconseja no llamar a useContext condicionalmente para evitar confusiones, especialmente para los desarrolladores inexpertos. Puede haber otros hooks además de useContext, como el hook de uso con Octobot, que también se pueden usar condicionalmente. ¡Gracias!

Con esta imagen completa de cómo funciona el contexto, podemos confirmar que, efectivamente, useContext puede usarse condicionalmente. No interfiere con otros hooks. Por eso es que useContext puede usarse condicionalmente. Y eso es todo lo que quería contarles sobre useContext, estos Curiosos Hooks.

¿Tengo un último minuto para hacer una advertencia? Tienes un último minuto para hacer una rápida advertencia, adelante. Gracias. Solo quería decir que no lo hagan. No llamen a useContext condicionalmente. Es mejor para los desarrolladores jóvenes mantenerlo de la misma manera que los demás para asegurarse de que no se pierdan.

Y también, una rápida pregunta. ¿Crees que puede haber otros hooks? ¿Es useContext el único? ¿Recuerdas, el hook de uso con Octobot? Dijimos que podríamos usarlo condicionalmente. ¿Por qué es eso? Y sí. Muchas gracias. Aquí hay algunos recursos si quieres seguir profundizando y seguir construyendo tu propio modelo mental del comportamiento de renderizado de amenazas. Eso fue increíble. Dame algo.

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)
Top Content
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!

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Top Content
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 Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Top Content
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
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
Top Content
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