Reactividad de Grano Fino Sin Ningún Compilador

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

Lograr una reactividad de alto rendimiento en React sin comprometer la experiencia del desarrollador siempre ha sido un desafío clave. Al construir aplicaciones en tiempo real diseñadas para mostrar cientos de millones de filas sin retraso notable, la reactividad de grano fino es esencial. Pero cuando comencé mi viaje en Pigment, ni Recoil, Jotai, ni Zustand eran lo suficientemente maduros, y React Compiler aún no existía. Vamos a explorar juntos cómo logramos ingerir, mostrar y actualizar grandes conjuntos de datos sin problemas, sin sacrificar la experiencia del desarrollador o del usuario.

This talk has been presented at React Day Berlin 2024, check out the latest edition of this React Conference.

Nicolas Dubien
Nicolas Dubien
29 min
13 Dec, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Mi nombre es Nicolas, y hoy voy a hablar sobre la Reactividad de Grano Fino sin el compilador esta vez. React es reactivo, pero vuelve a renderizar componentes innecesarios. La reactividad de grano fino se logra actualizando elementos específicos en lugar de componentes completos. Pigment encontró problemas de reactividad al construir tableros de datos financieros en tiempo real. Crearon su propio sistema reactivo sobre React para lograr una reactividad de grano fino. Usaron hooks personalizados como useShell, useComputed y useWatch para integrar React con su sistema reactivo. También consideraron usar JavaScript nativo para la optimización, pero optaron por preservar React. Usan bibliotecas externas como Zestand para flexibilidad, y mantener la reactividad durante las actualizaciones de React no ha sido un problema.

1. Introduction to Fine-Grain Reactivity

Short description:

Me llamo Nicolas, y hoy voy a hablar sobre la Reactividad de Grano Fino sin el compilador esta vez. Primero necesitamos entender de qué se trata la Reactividad y si React es reactivo hoy en día. Veamos si React es reactivo considerando una aplicación simple compuesta por tres contadores. Para que funcione correctamente, necesitas mover los estados más arriba en el árbol y pasar props hacia abajo a los contadores y el total. El componente de la aplicación es el componente principal en esta aplicación, compuesto por tres estados pasados a cada contador. Esta es una aplicación básica.

Me llamo Nicolas, y hoy voy a hablar sobre la Reactividad de Grano Fino sin el compilador esta vez. Esta es la última charla antes del lanzamiento. Después de eso, podrán almorzar, así que por favor quédense.

Pero antes de entrar en la Reactividad de Grano Fino, primero necesitamos entender de qué se trata la Reactividad y si React es reactivo hoy en día. Para entender de qué se trata la Reactividad, tomé esta definición del ecosistema de Vue. Cuando modificas el estado, la actualización de Vue hace que la gestión del estado sea simple e intuitiva. Tenemos otra versión de esta, que simplemente dice que el DOM o el Vue es una función del estado.

Así que la primera pregunta que deberíamos hacernos es, ¿es React reactivo o no? Y para responder a esa pregunta, una cosa muy simple de hacer es simplemente intentarlo y ver si React es reactivo. Así que para hacer eso, consideraré esta aplicación muy simple. Está compuesta por tres contadores. Así que las primeras tres líneas son solo contadores. Puedes incrementar, decrementar los contadores, y puedes ver el valor del contador. Al final, tienes la última línea, y la última línea es solo el total de los tres contadores arriba.

Si fueras a construir tal aplicación, podrías llegar a algo como eso, con tres componentes principales, un componente de aplicación, un componente de contador y un total. Y obviamente, dentro de tu aplicación, usarás el componente de contador tres veces. Pero con ese, no funciona tan bien. Necesitas poner algo, diría yo, de interactividad para que los usuarios puedan usar tus contadores. Así que pondrás algunos estados directamente dentro de los contadores, y con eso, solo podrás jugar con cada uno de los contadores independientemente. Puedes incrementar, decrementar tus contadores, y estará bien para los usuarios. Pero en algún momento, necesitas el total, y si necesitas el total, necesitas saber sobre el estado de cada uno de estos contadores directamente dentro de tu total. Y en este punto, el truco habitual es mover los estados más arriba en el árbol, y así obtenemos los primeros tres estados directamente en la aplicación, y simplemente mueves los props hacia abajo a los contadores y al total.

Ahora que tenemos todo, veamos cómo funciona al final. Así que veamos cuál es el código de este componente de aplicación, porque es el componente principal en toda esta aplicación. Así que simplemente, así es como será tu componente de aplicación en ese caso. Así que mi componente de aplicación está compuesto por tres estados. Cada uno tiene un valor y un conjunto de valores. Y puedes ver que paso el valor más la función de establecimiento directamente a cada uno de los contadores. Y al final, puedes ver el componente total, que está recibiendo los tres valores. Esta es una aplicación básica.

A la derecha de la pantalla, puedes ver la aplicación en acción. Así que solo estoy jugando con esta aplicación.

2. Reactivity and the React Compiler

Short description:

Estoy incrementando, decrementando contadores, y puedes ver que todo funciona bien. React es reactivo, ya que los valores en mi estado se replican correctamente en la pantalla. Sin embargo, cuando habilito las React DevTools, veo que cada vez que incremento o decremento un contador, no solo se renderizan ese contador y el total, sino también todos los demás contadores y el componente de la aplicación. Recientemente, intenté usar el compilador y noté una ligera diferencia. Se renderizan el contador y el total, pero también se renderiza el componente de la aplicación. Quería entender qué estaba haciendo el compilador, así que revisé el playground con el código.

Estoy incrementando, decrementando contadores, y puedes ver que todo funciona bien. Así que React es reactivo, porque al final, cuando hago clic en algo, puedo ver que los valores que he instalado en mi estado se replican correctamente en la pantalla. Puedo ver el total siendo actualizado, puedo ver los valores siendo actualizados. Pero hay algo que habilito en las React DevTools que está resaltando todo en la pantalla. Cada vez que hago clic en algún lugar, algo está resaltado. Todo lo que está resaltado está relacionado con una cosa de renderizado. Así que cada vez que React está renderizando uno de mis componentes, puedes ver esta pequeña flecha detenerse alrededor del componente. Significa que mi función ha sido llamada de nuevo. Y en mi caso, puedes ver que cada vez que incremento o decremento un contador, no solo este contador más el total tiene que ser renderizado de nuevo, sino también todos los demás contadores más la aplicación en sí.

La primera vez que vi eso, pensé, ¿qué está haciendo React? Es una locura. Quiero decir, ¿qué demonios? Quiero decir, estoy incrementando un contador, y todo se vuelve a calcular una y otra vez. Y tuve que aceptarlo. Quiero decir, estaba bien. Pensé, tal vez es normal. Digamos que es normal. Y recientemente, me encontré con cosas del compilador. Pensé, sí. Seré salvado. Tal vez seré salvado esta vez. Habilité el compilador, de nuevo, el código que te mostré. Esta vez, obtenemos algo un poco diferente. Cuando incremento el contador, solo vemos un renderizado de este contador más el total, obviamente. Pero también vemos un renderizado del componente de la aplicación. Así que mejora. Es mejor, o al menos, diremos que es más intuitivo. Pero como el compilador está haciendo algo muy extraño, quería echar un vistazo a lo que estaba haciendo.

Así que revisé el playground con ese fragmento de código. Así que si alternamos el playground del compilador de React contra ese fragmento de código, obtenemos lo siguiente más precisamente, este código. No pasaré demasiado tiempo en ello. Pero hay una pregunta.

3. Fine-Grained Reactivity and Journey at Pigment

Short description:

¿Está el compilador de React haciendo reactividad de grano fino? En un sistema reactivo de grano fino, las actualizaciones no son a nivel de componente, sino más profundas en el árbol, afectando directamente a elementos específicos. El compilador de React, como se vio antes, no es reactivo de grano fino porque todavía vuelve a renderizar la aplicación innecesariamente. Hablemos de la reactividad de grano fino y mi experiencia como ingeniero de software principal en Pigment, donde encontramos problemas de reactividad y encontramos soluciones. Sígueme en redes sociales y revisa mi biblioteca de código abierto, TestCheck. Ahora, exploremos cómo hacer que nuestra aplicación sea más reactiva discutiendo nuestro viaje en Pigment y examinando un ejemplo de países que no se actualizan correctamente.

¿Es la herramienta adecuada para usar con el fin de lograr esta reactividad? No responderé a esa pregunta, honestamente. Pero es importante tener en cuenta que tal vez pueda ser la herramienta adecuada. Tal vez no sea la herramienta adecuada. Pero la pregunta principal que deberíamos hacernos, porque la charla trata sobre reactividad de grano fino, es, ¿está el compilador haciendo reactividad de grano fino al final? Y para entender si está haciendo o no reactividad de grano fino, necesitamos entender de qué se trata la reactividad de grano fino. Así que tomaré la definición de Solid JS. Y la definición es la siguiente. En un sistema reactivo de grano fino, una aplicación no tendrá la capacidad de hacer actualizaciones altamente dirigidas y específicas. Lo importante allí es que las actualizaciones no son a nivel de componente. Están más profundas en el árbol. Están directamente en el span que contiene el valor del contador. En el caso de esta presentación, no profundizaré tanto en este tema de reactividad de grano fino. Me detendré a nivel de componente. Pero incluso a nivel de componente, si fuéramos reactivos de grano fino, habríamos esperado volver a renderizar el contador y el total, pero no la aplicación. Así que lo que hemos visto justo antes con el compilador de React no es ni siquiera reactivo de grano fino en absoluto, porque nos perdimos, todavía volvimos a renderizar la aplicación por nada. Así que hablemos un poco sobre la reactividad de grano fino. Pero antes de llegar allí, solo te diré un poco quién soy y por qué estoy hablando sobre reactividad de grano fino hoy. Mi nombre es Nicolas Dubin. Trabajo como ingeniero de software principal para Pigment. Pigment no es Pigment CSS, porque muchas personas me preguntan sobre eso, así que prefiero decirlo. Y en Pigment, estamos mostrando grandes cuadrículas de datos con millones de celdas y gráficos por todos lados. Y tuvimos algunos problemas con la reactividad de React, y tuvimos que idear soluciones para hacer que la aplicación fuera lo suficientemente reactiva para que los clientes estuvieran contentos con ella. Puedes seguirme en algunas redes sociales. Tengo algunas allí. Y como dijo Nathaniel, soy el autor de la biblioteca de código abierto, TestCheck. Así que tal vez la conozcas o no. Y puedes encontrar más sobre Pigment en engineeringpigment.com. Pero pasemos al tema principal de esta charla, cómo hacer que nuestra aplicación sea un poco más reactiva. Y te guiaré a través de nuestro viaje en Pigment. Así que en Pigment, cuando nos encontramos con este ejemplo muy simple sobre países que no se actualizan de la manera correcta, queríamos entender qué estaba pasando, y si podíamos hacerlos mejor. Y lo primero que hicimos fue simplemente retomar este ejemplo e intentar entender qué estaba saliendo mal con este.

4. Re-rendering and Performance Optimization

Short description:

Analizamos un ejemplo donde cambiar el estado de un componente en React desencadena una re-renderización de todo el componente de la aplicación y sus hijos. Esto se debe a las reglas de React. El uso de context en React también puede llevar a re-renderizaciones. Para mejorar el rendimiento, aplicamos memoization al componente contador. Comenzamos nuestro viaje en Pigment con el objetivo de mejorar nuestro código y hacerlo más eficiente.

Tomamos este ejemplo, y consideramos la idea de que incrementaremos uno de estos países y trataremos de entender qué está pasando. Así que decidimos decir que el tercer país en este ejemplo, que es verde, todo el valor verde se moverá al valor rojo. Así que hagámoslo. Y lo primero que sucedió allí es que React volverá a renderizar el componente de la aplicación. Y la razón de eso es que en React, cada vez que cambias el estado de un componente, este componente tiene que ser re-renderizado. Esta es una de las reglas de React. Y esto funciona de esa manera porque ha sido diseñado de esa manera. Así que tienes que volver a renderizar el componente de la aplicación, no importa por qué tienes que volver a renderizar eso, porque está manteniendo tu estado.

Lo siguiente es sobre todos los demás componentes. La segunda regla en React es que cada vez que un componente se vuelve a renderizar, todos los hijos de este componente también se volverán a renderizar. Así que tenemos que volver a renderizar contador, contador, contador y total. Y esta es la razón principal por la que todo se volvió a renderizar la primera vez. Necesitamos volver a renderizar la aplicación porque está manteniendo el estado. Necesitamos volver a renderizar todos los países porque todos los países son hijos del componente de la aplicación. Y el componente de la aplicación se volvió a renderizar. Y hay uno último. Solo quiero mencionarlo porque es bastante importante. La mayoría de las veces, la gente se queja de que el context es lento. Y una de las razones de que el context sea lento es porque cada vez que usas context en React, puedes considerar que el valor de tu context es una especie de estado del componente que consume el context. Así que significa que cada vez que usas un context, estarás sujeto a re-renderizaciones, como si el estado cambiara directamente dentro de tu componente usando el context. No estamos usando context en este caso, así que estamos bien con este. Pero intentemos mejorarlo. Hagámoslo incrementalmente. Cuando comenzamos Pigment hace cinco años, comenzamos con este fragmento de código, digamos. Y la idea era mejorarlo. Entonces, ¿cómo podemos mejorarlo? La primera idea es que podemos caer en un internet sobre memorizar cosas. Así que simplemente pusimos cosas de memo alrededor del contador. Así que esto es lo que hice allí. Y ahora que tengo las cosas de memo y mi aplicación, puedo simplemente rehacer la verificación con eso junto antes. Todavía tengo esta aplicación, pero cometí un error tipográfico en la diapositiva inicialmente porque tenemos varios props para los países.

5. Stability of Props and useCallback

Short description:

Tenemos dos props para cada país: valor y función incremental. Al actualizar el tercer contador, necesitamos volver a renderizar el componente de la aplicación. React calculará las nuevas propiedades para cada contador, pero la función de incremento no es estable. Podemos usar useCallback para estabilizarla.

Puedes ver que tenemos dos props para cada país, una que es el valor y otra que es la función incremental. Realizaremos exactamente la misma actualización que antes, jugaremos con el tercer contador. Así que movemos el tercer contador de verde a rojo, igual que antes, necesitamos volver a renderizar el componente de la aplicación. No tenemos otra opción. Esta es la primera regla de React. Así que tenemos que hacerlo.

Luego React renderizará el componente y calculará las nuevas propiedades de cada contador. Pero el problema es que para cada contador, recibimos dos propiedades. Una de ellas será estable, el valor. Para el contador uno, por ejemplo, el valor sigue siendo azul. Solía ser azul antes. Pero también recibe otra cosa, que es otra propiedad, que es la función de incremento. Y esta ya no es estable. La razón de eso es que cuando ves este código, cada vez que llamamos a la función de la aplicación, recreamos una nueva función de incremento. Porque incremento es solo una función lambda. Así que no es estable en absoluto. Cada vez que llamamos a la aplicación, creamos una nueva. Así que hay un truco para hacerla estable, que es simplemente usar useCallback.

6. Reactivity at Pigment

Short description:

Queríamos ser más reactivos y tener una reactividad más detallada en Pigment mientras construíamos tableros para mostrar datos financieros en tiempo real. Los datos necesitan actualizarse con frecuencia para asegurar que todos los usuarios puedan verlos en tiempo real.

Con ese fragmento de código, simplemente alcanzamos lo que el compilador de React estaba haciendo principalmente. Pero, como dije, no somos reactivos de manera detallada. Todavía tenemos cosas que se vuelven a renderizar y que no deberían hacerlo. Así que les contaré sobre Pigment, sobre lo que hicimos en Pigment. Porque no era suficiente para nosotros jugar con memo cada vez, y estaba añadiendo un poco de complejidades extra a la base de código. Así que queríamos hacer algo un poco diferente.

Para hacerlo más simple para los desarrolladores, pero también para ser más reactivos, más detalladamente reactivos. Así que en Pigment, estamos construyendo tableros para mostrar datos financieros de clientes. Estos datos financieros pueden mostrarse como gráficos, como cuadrículas. Y pueden contener múltiples tipos de datos, incluyendo formato, cifras y texto. Todos los datos son en tiempo real. Las personas quieren ingresar datos, y quieren que todos sus colegas al otro lado del mundo vean los datos en su tiempo real. Esto significa que tenemos que actualizar los datos varias veces por minuto, varias veces por hora, dependiendo del uso de la plataforma.

7. Fine-Grained Reactivity for Real-Time Data

Short description:

Los datos allí son muy simples. Tenemos grandes clientes con millones de celdas. Usamos context para etiquetas, pero puede tener problemas de rendimiento. Construimos nuestro propio sistema reactivo sobre React para lograr una reactividad detallada para datos en tiempo real.

Los datos allí son muy simples. Está compuesto solo por algunas cifras. ¿Qué pasa con mi pollo? Porque solía tener pollo en el pasado, y puedes ver el número de huevos de cada uno de ellos. Es un dato privado, así que por favor no le saques fotos. No, puedes hacerlo.

Y así, este es bastante pequeño, pero puedes imaginar que tenemos grandes clientes con millones de celdas, que ni siquiera caben en Excel en general. Así que no solo renderizamos cuadrículas pequeñas como esta. De lo contrario, habría sido simple.

Y también tenemos etiquetas. Las etiquetas se han utilizado en todas partes. Así que tenemos etiquetas que están sincronizadas con todos los gráficos, todos los diagramas. Así que necesitamos colocarlas en algún lugar, que sea compartido entre todos ellos. Y hoy, usamos context. Y como dije, context tiene algunos problemas con el rendimiento si no se usa de la manera correcta. Y así tenemos datos en tiempo real en todos los lugares con componentes compartiendo estos datos entre unos y otros.

Esta es solo la cuadrícula en Pigment. Y allí puedes verla en acción. Así que tenemos un usuario que está jugando con la cuadrícula. Alguien está cambiando los datos. Y puedes ver donde hay una nueva renderización de componentes. Y puedes ver que solo las celdas que han sido tocadas, solo los errores que han sido tocados se volverán a renderizar en la pantalla. Para lograr eso, tuvimos que construir nuestro propio sistema reactivo sobre React. Y así es como funciona. Así que tomamos esta cuadrícula muy simple. Esta es una cuadrícula pivotada. Así que si jugaste con Excel en el pasado y si hiciste cosas de datos pivotados, una cuadrícula pivotada se inicia desde un archivo CSV plano. Así que tienes un conjunto plano de líneas. Y tienes una configuración que te dice cuáles son las columnas, cuáles son las filas en tu cuadrícula para ser mostradas. En ese caso, mis columnas son el tipo de pollo, así que Sussex y Azure, y el nombre del pollo. Ambos tienen nombres.

8. Details of Data Configuration and Algorithm

Short description:

En la cuadrícula, los errores pueden abarcar múltiples columnas y filas. Cada celda tiene una ubicación específica. El algoritmo utiliza datos en formato CSV con columnas especificadas. Las líneas pueden estar desordenadas. La configuración incluye tipo, pollo y año.

Uno de ellos se llama Bianca, el otro Bernard, y uno es Jasmine. Así que es solo mi configuración. En las columnas, tengo el tipo, luego el nombre. Y en las filas, solo tengo los años. Algo muy importante a notar en esta visualización es que algunos errores abarcan múltiples columnas. También puede ser sobre múltiples filas. Y también hay algo interesante.

En las cuadrículas pivotadas, tienes alguna ubicación para cada celda. Así que, por ejemplo, el valor 166 es para Sussex, Bianca, y 2020. Puede ser interesante saberlo en el algoritmo porque lo necesitamos en algún momento para obtener los datos correctos. En términos de datos que recibimos en el algoritmo, son principalmente líneas. Así que es solo plano con todos los detalles. Así que puedes verlo como un CSV con todas las columnas especificadas. Sussex, Bianca, 2020, 166. Estas líneas pueden estar desordenadas. Y luego tenemos la parte de configuración. Tipo, pollo, y año.

9. Algorithm Overview and React Compiler Limitations

Short description:

Voy a mostrarles rápidamente el algoritmo. Tomamos la línea más la configuración, calculamos los errores de la visualización y renderizamos las filas, columnas y celdas. Tenemos un componente con controles adicionales. Cuando volvemos a renderizar elementos, incluido el componente de cuadrícula, el compilador de React no funciona bien. Necesitamos encontrar otra solución.

Voy a mostrarles rápidamente el algoritmo. No profundizaré demasiado en los detalles de este algoritmo. Tienen una copia de él directamente en mi GitHub.

Lo importante es que realmente tomamos la línea más la configuración, lo que significa que tomamos el CSV más la configuración. Luego necesitamos calcular cuáles serán los errores de esta visualización, cuánto se extienden, si se extienden en múltiples columnas o múltiples filas, y cuáles son las rutas de cada columna. Y al final, saber que tenemos todo. Podemos simplemente renderizar las filas, las columnas y las celdas. Para filas y columnas, son básicamente los errores.

Sepan que tenemos un componente listo. Podemos ponerlo en acción para que podamos poner algunos controles adicionales encima de él para que podamos jugar con él y ver si es reactivo o no. Quiero decir, reactivo de grano fino o no. Y así esta es la visualización. Tengo dos botones. Uno de ellos es actualizar datos. Es solo sincronizar los datos desde el backend. Y los datos son los mismos. Y uno de ellos es actualizar una celda. Está actualizando la primera celda en la esquina superior izquierda.

En ambos casos, pueden ver que todos los elementos han sido re-redondeados. Así que no, quiero decir, volvemos a renderizar todas las celdas, volvemos a renderizar todos los errores, incluso volvemos a renderizar el componente de cuadrícula en sí. Pero afortunadamente, hoy tenemos el compilador de React, así que probablemente estemos seguros y podemos detener esta charla en este punto. Pero cuando comenzamos Pigment, no era el caso. Pero vamos a intentarlo. Y no funciona tan bien. Así que nos alejaremos de él por ahora. Pero sí, el compilador de React no está haciendo mucho para este caso. Probablemente sea demasiado complejo para que pueda hacer algo. Tal vez tengamos que cambiar la forma en que codificamos nuestro componente para que funcione. Pero en este momento, con ese fragmento de código, no tiene éxito. Así que de todos modos, tuvimos que idear algo más.

10. Creating a Custom Value with useShell

Short description:

Hace cinco años, no había compilador de React ni sistema que nos ayudara. El hook useState es la principal causa de nuestros problemas. Queremos preservar useState, así que creamos nuestro propio valor con useShell. Es similar a useState pero no desencadena re-renderizados. React ignora los cambios realizados con useShell.

Porque hace cinco años, no había compilador de React, ni sistema, ni cosas así para ayudarnos en esa área. Pero hay una cosa que nos gusta en React. Esto es este useState. Y esta es la principal razón de todos nuestros problemas. Porque cuando usamos useState, cada vez que el estado cambia, tenemos que volver a renderizar el componente. Así que arriba. Así que esto no es genial. Pero queremos preservar useState. Es genial. Quiero decir, la gente está acostumbrada a usar este tipo de abstracción. Quieren algo que se parezca a useState.

Entonces, ¿qué pasa si creamos nuestro propio valor? ¿Qué pasa si decimos que tenemos un useShell, que está creando un shell? Así que veamos qué significa. useState toma un valor y devuelve este valor más un setter. Así que esta vez es azul. Cuando llamamos a la función setter, actualizamos el valor. Lo movimos a verde. useShell será un poco similar de alguna manera. Así que toma un valor como useState. Pero devuelve un shell que contiene este valor más una función setter. Cada vez que configuras la función, no cambias el shell. Pero cambias el valor, que está dentro del shell. Desde el punto de vista de React, React no ve nada. Considera que el estado es el mismo. Así que no volvemos a renderizar nada.

Así que en este punto, solo estamos diciendo, React, por favor ignora mis cosas. Funciona detrás de escena. Así que esta es solo una posible implementación para ello. Puedes cambiarlo como quieras. Internamente, todos los shells están hechos de behavior subjects.

11. Integrating React and Updating Shells

Short description:

No necesitas saber sobre behavior subjects. Construimos un estado con un behavior subject para crear nuestro shell. Pero necesitamos algo diferente porque no podemos trabajar solo con el valor. Así que creamos useComputed, que transforma shells en nuevos shells. Nos suscribimos al shell original y reenviamos actualizaciones al shell de mapa. Con esto, tenemos shells en todas partes, pero necesitamos integrar React para ver las actualizaciones.

Pero de todos modos, no necesitas saber sobre behavior subjects para entender el resto de la charla. La idea de un behavior subject es que es algo a lo que puedes suscribirte para obtener actualizaciones. Y obtienes un valor sincronizado. Tienes un valor cuando creas los componentes. Para crear nuestro shell, construimos un estado. El estado es solo un behavior subject. Y para actualizar el contenido del shell, creamos una función setter, que simplemente coloca el nuevo valor directamente en el behavior subject. Nada más.

Ahora que tenemos nuestro shell, tenemos un problema. Porque las líneas ya no son líneas. Tenemos shells sobre líneas. Así que necesitamos algo diferente. Porque no funcionará. Podemos hacer algo, pero si no tenemos el valor, no podemos hacer nada desde el valor. Así que necesitamos cambiar este código. En este punto, lo que queremos hacer es crear un nuevo shell. Porque en realidad no necesitamos el valor. Simplemente derivamos el valor en algo nuevo. Así que creamos otro ayudante, que se llama useComputed. useComputed toma los shells, o múltiples shells, y los transforma en otro shell. Usualmente la firma es la siguiente. Así que tomamos una función de transformación. Esta está transformando azul en verde, un shell, que tiene un valor azul, y devuelve un nuevo shell, que contiene el valor transformado. En términos de implementación, useComputed está creando un shell. Así que simplemente creamos un shell, usando useShell, el primer ayudante que ideamos. Luego tenemos que registrarnos en el shell original, para saber cuándo hay una actualización en el shell original, y reenviar esta actualización directamente dentro del shell de mapa. Así que lo que hacemos es simplemente, tomamos el shell, nos suscribimos a este shell, y cada vez que hay una actualización, colocamos ese valor directamente dentro del shell de mapa, simplemente haciendo como una función setter en el shell de mapa. Con todo eso, ahora podemos tener shells en todos los lugares. Pero en algún momento, simplemente cortamos React, porque React no está al tanto de la actualización. Así que necesitamos conectar React en algún momento, porque necesitamos ver la actualización directamente visible en React.

12. Reactivity and useWatch

Short description:

Necesitamos devolver la reactividad creando un shell usando el ayudante useWatch. useWatch conecta el shell a React y le indica que vuelva a renderizar el código. Desempaqueta el shell y le da el valor a React, transformando el valor azul en verde. Utiliza la función useSyncExternalStore de React para suscribirse a las actualizaciones del shell y proporcionar el valor a React de manera sincrónica.

De lo contrario, simplemente perdemos la reactividad por completo, porque ya no tenemos reactividad en este punto. Así que necesitamos devolver la reactividad, y para hacerlo, puedo crear un shell una vez más. Pero necesito algún nuevo ayudante, que es useWatch, que será responsable de conectar el shell a React, y decirle a React, OK, esta vez te necesito. Tengo un valor para ti, y necesitas volver a renderizar este fragmento de código. Y esto es lo que hace useWatch. useWatch simplemente toma un shell, desempaqueta el shell, y te da el valor para React. Y le dirá a React, OK, este azul ya no es azul. Ahora es verde. Y esto es lo que está haciendo. Cómo funciona detrás de escena. Así que estamos tomando un shell. Usamos una función de React, que se llama useSyncExternalStore. Podemos recibirla como dos funciones, suscribirse y obtener instantáneas. Así que tenemos que suscribirnos al shell para saber cuándo hay una actualización de este shell. Y tenemos que decirle a React de qué se trata este valor, de manera sincrónica con getSnapshots. Esto es básicamente useWatch de una manera simplificada.

13. Plugging Everything Together

Short description:

Después de conectar todo, vemos que no se necesita volver a renderizar. Al actualizar un shell, se logra el valor de renderizado deseado. La optimización siempre debe ser útil y medida para su utilidad futura. Visita el sitio web de la empresa o consulta el repositorio FASTCHECK.

Ahora que tenemos todo junto, podemos simplemente conectarlo a nuestra aplicación y ver qué sucede. Así que esta es la misma aplicación de antes, los mismos botones, y esta vez estoy presionando actualizar datos, y puedes ver que no hay que volver a renderizar nada. Todo se ha omitido. No volvemos a renderizar nada. Y cuando hago clic en actualizar un shell, solo veo un valor de renderizado en la parte superior del shell que ha sido actualizado. Esto es lo que queríamos lograr.

Y antes de terminar con esta charla, solo quería decirte algo porque pasamos por ese camino después de, diría, varios meses iterando sobre la optimización de nuestra aplicación. Tuvimos que hacerlo, no porque estuviéramos contentos de hacer otro sistema de reactividad sobre React, sino porque era necesario y medimos que era un problema tener cosas de reactividad que no eran tan reactivas. Así que una cosa que diré es que, siempre que hagas optimización, no solo este tipo de optimización, sino también asegúrate de hacer algo que sea útil y siempre mide que es útil y será útil en el futuro. Y creo que eso es todo por hoy.

Aún puedes visitar el sitio web de mi empresa si quieres. Y de lo contrario, tienes el nombre de mi repositorio, FASTCHECK. Y eso es todo por mi parte.

QnA

Optimizing with Native JavaScript or React

Short description:

Bianca, la reina ponedora de huevos, tuvo una drástica disminución en la producción de huevos. Consideramos usar JavaScript nativo para la optimización, pero decidimos preservar React por simplicidad y facilidad de incorporación. Muchos factores deben considerarse antes de tomar una decisión.

Antes de hacer eso, quiero hablar sobre Bianca. Bianca es la gallina, la reina ponedora de huevos. Lo estaba haciendo genial. Tenía tantos huevos. ¿Qué pasó en el último año? Simplemente cayó en picado. Sí, fue horrible. Diría que murió en algún momento.

OK, espera, espera. Solo una pregunta rápida. Cuando dices murió, eso podría tener un tono oscuro. ¿Tuviste cena de pollo en algún momento en 20... OK, OK, solo comprobando. Solo comprobando. Muy bien. Vamos a centrarnos en las preguntas importantes aquí que han sido votadas por todos.

Así que la primera pregunta es, y una cosa que pudimos ver mientras revisabas las soluciones, había cada vez más complejidad ocurriendo. Michael, creo que Michael, estoy pronunciando tu nombre correctamente, espero. ¿Has considerado usar solo JavaScript nativo para esta solución en lugar de optimizar la reactividad?

Sí, inicialmente había una pregunta sobre como... No estoy seguro de si responderé totalmente a la pregunta, pero había la pregunta de dejar totalmente React e ir nativo para este componente, este componente preciso. Así que queríamos en algún momento decir, OK, la cuadrícula es demasiado lenta y los usuarios se quejarán todo el tiempo. Uno de los puntos que la gente puede agregar en este momento fue que React nunca podrá resolver este tipo de problema. No era... No habría sido capaz de soportar este tipo de cosas. Así que muchas personas empujaron a simplemente dejar React totalmente y simplemente construir, diría, como JavaScript nativo, cosas de HTML al lado, que harán lo mismo pero de una manera reactiva. Y en este punto, siento que quería preservar React porque siento que es mejor, será más simple para que las personas se integren en la empresa, tener una solución clásica, incluso si está detrás de los hooks, básicamente lo que usan es solo nativo. Quiero decir, son solo hooks al final. Así que solo tienen que saber un poco sobre la abstracción, es solo cuestión de tres hooks y pueden construir una UI.

Genial, muchas gracias. Siento que hay muchos factores que entran en esa decisión. Y probablemente para ti, puede que tengas que mirar las diferentes cosas en tu organización antes de tomar una decisión.

Using Zestand and Maintaining Reactivity

Short description:

Zestand no era lo suficientemente importante como para intentarlo, pero siempre extraemos el código en una pieza específica de nuestra base de código para flexibilidad. La implementación detrás de escena es un detalle para los usuarios finales de Pigment. Mantener la reactividad adicional no ha sido un problema durante las actualizaciones de React. Es una compensación entre hacerlo nosotros mismos o usar bibliotecas externas. El lanzamiento de React Compiler no hizo que este trabajo fuera obsoleto.

Una respuesta clásica, depende. Me encanta.

Bien, la siguiente viene de forma anónima. No estoy seguro de entender totalmente la pregunta, pero te la voy a plantear y tal vez puedas... ¿Cuál es la diferencia frente a simplemente usar Zestand? Diría que, en el pasado, Zestand no era lo suficientemente maduro. Así que cuando comenzamos, hace como cinco años, Recode estaba allí, acababa de empezar a estar allí, y Zestand apenas se estaba mostrando. No era realmente una opción en ese momento. No era lo suficientemente maduro para intentarlo, así que nunca lo intentamos. La cuestión es que siempre intentamos extraer este código en una pieza específica de nuestra base de código, para que si un día queremos reemplazar la forma en que el use watch está funcionando detrás de escena, aún podamos decir, está bien, esto es Zestand y ahí está la escena. Hoy no es Zestand, es el que te mostré. Pero tal vez algún día podamos, como, decir, está bien, queremos usar Redux, queremos usar MobX, queremos usar Zestand, Jotar, cualquier solución detrás de escena. Solo un detalle de implementación. Quiero decir, para los usuarios finales de Pigment, como los desarrolladores que están usando estos hooks, es solo cuestión de usar el use shell, usar el use watch y usar el use computed. Cualquiera que sea la implementación bajo la escena es un detalle. Así que tal vez algún día será Zestand. Tal vez no. Eso es agradable. No, seguro. Y me gusta el hecho de que no solo estás pensando en la solución, sino pensando en cómo la experiencia de tu equipo al usar esta solución es realmente buena.

Y tenemos una pregunta de Andre, que es que se ve genial y parece bastante complejo. ¿Crees que vale la pena la complejidad, considerando que vas a tener que mantener esta extra reactividad que has construido en el futuro, especialmente a medida que React continúa cambiando? Sí, ha sido una pregunta durante mucho tiempo. Cuando comenzamos estábamos en React 16, y hasta ahora, nos detuvimos en 18 por ahora. Pero nunca tuvimos problemas al migrar este. Quiero decir, todo el asunto alrededor de estos tres hooks está altamente probado, e incluso las pruebas pasaban de una versión a otra. No es la parte que se rompió cuando pasamos a otras versiones de React. Es bastante limitado y el tamaño del código es bastante limitado para estar seguro. Siempre este tipo de compensación entre hacerlo por tu cuenta o tomar una biblioteca externa para hacerlo por ti. Pero hicimos eso en el pasado porque otras soluciones no estaban alineadas con lo que estábamos buscando, o tal vez simplemente nos perdimos la solución en el pasado. Y esto es parte de ambos problemas, creo, al mismo tiempo. Cuando se lanzó React Compiler, ¿te preocupaste por un segundo, o que este trabajo fue obsoleto instantáneamente? No, no lo creo.

Remaining Questions and Closing Remarks

Short description:

Todavía lo necesitaremos en varios lugares, pero no para este caso específico. El pollo vino primero. La pregunta favorita de Nicolas es sobre ir a nativo y darse cuenta de que el problema no es la biblioteca, sino cómo la usamos.

Creo que todavía tendremos que necesitar este. Quiero decir, no está resolviendo todos los problemas. Creo que ayudará, honestamente. {{^}}Creo que lo necesitaremos. Necesitaremos conectarlo porque ayudará mucho en varios lugares. Pero para este lugar específico, no lo hará.

Genial. No, seguro. Y la última pregunta, la guardé hasta el final. No la omití. ¿Qué vino primero, el pollo o el huevo? Fue el pollo, en mi caso.

No sé para otros, pero fue el pollo. El pollo. En su caso, fue el pollo. Eso fue genial. Nicolas, antes de que nos vayamos y antes de que te den un aplauso, ¿cuál fue tu pregunta favorita hasta ahora? Me gusta bastante la sobre ir a nativo porque creo que es una de las preguntas que la gente puede hacerse. Quiero decir, cada vez que usas una biblioteca, a menudo piensas que el problema es la biblioteca y la forma en que usas la biblioteca. Fue la pregunta con la que nos encontramos en Pigment durante unos meses hasta que dijimos, está bien, el problema no es la biblioteca. La biblioteca es capaz de hacer cosas que son rápidas. El problema es cómo lo hicimos. Genial. Muy bien.

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

SolidJS: Reactivity Unchained
JSNation 2022JSNation 2022
20 min
SolidJS: Reactivity Unchained
Solid.js is a declarative JavaScript library for building user interfaces that addresses performance optimization. It introduces fine-grained reactivity and avoids using a virtual DOM. The Talk explores rethinking performance and reactivity in web applications, understanding reactivity and primitives, and creating DOM elements and using JSX in Solid.js. It also covers rendering components, sharing state, and the advantages of fine-grained rendering and the reactive approach in Solid.js.
5 Años de Construir React Table
React Summit 2022React Summit 2022
24 min
5 Años de Construir React Table
Top Content
React Table is a popular table library that started with HTML5 tables and transitioned to React. It faced challenges with integration and user requests, leading to the development of React Table. The introduction of the Headless UI pattern and TypeScript support improved the library's capabilities and quality. Generics and TypeScript played a significant role in reducing the code size and improving development. React Table is now going framework agnostic and partnering with AG Grid.
Gestión de Estado Moderna con Vue 3
Vue.js London Live 2021Vue.js London Live 2021
22 min
Gestión de Estado Moderna con Vue 3
Top Content
Vanessa introduces Vue Free and discusses the benefits of using the Composition API. The order of execution and grouping logical units using the Composition API is explained. The Composition API is used for state management and refactoring components. The speaker shares their initial experience with state management using Vuex. Composables are explored as an alternative for state management in Vue 3.
Llevando Vue.js al Backend
Vue.js London Live 2021Vue.js London Live 2021
23 min
Llevando Vue.js al Backend
This talk explores using Vue.js in the backend, specifically focusing on Vue 3 Reactivity. It discusses how Vue 3 Reactivity leverages ES6 proxies to update changes and intercept hooks. The talk also covers implementing Vue.js backend with live demos, showcasing the modification of proxies and the use of reactive functions. It demonstrates the creation of a reactive array and the implementation of join, leave, and message functionalities. The talk concludes by mentioning the possibility of using computed properties and inviting further questions.
Por Qué React No Debería Adoptar Signals
React Advanced 2024React Advanced 2024
10 min
Por Qué React No Debería Adoptar Signals
Today I want to talk about why React should not adopt signals. By adopting signals in React, we can automatically track dependencies for effects and memos, leading to more efficient component rendering. Accessing specific parts of the JSX that read signals allows for fine-grained reactivity across component boundaries. Adopting signals in React requires migrating to single execution components, which only update specific parts of the application. This can become complex when dealing with components that read from different signals. In contrast, React assumes everything can change and enforces this assumption through linters and compilers, leading to more robust code and easier updates. If you're interested in signals in React or need performance improvements, let's chat!
Construye Tu Propia Reactividad: Un Análisis Profundo de los Signals
JSNation 2025JSNation 2025
28 min
Construye Tu Propia Reactividad: Un Análisis Profundo de los Signals
Karl Vorden introduces signals for reactivity in JavaScript, aiming to demystify its implementation for better understanding. Signals in JavaScript provide efficient reactivity by updating only the necessary code without extra work. Different frameworks offer signal implementations like createSignal in solid JS, resembling React's useEffect but functioning differently. Vue signals are called refs, created with the ref function, returning an object with a value property. Define effect functions for tracking changes and execution in reactive signals. Explore computed functions for complex operations within reactive signals. Beware of pitfalls with conditionals affecting signal execution.

Workshops on related topic

Construye una Biblioteca Universal de Datos Reactiva con Starbeam
JSNation 2023JSNation 2023
66 min
Construye una Biblioteca Universal de Datos Reactiva con Starbeam
WorkshopFree
Yehuda Katz
Yehuda Katz
Esta sesión se centrará en los bloques de construcción universales de Starbeam. Usaremos Starbeam para construir una biblioteca de datos que funcione en múltiples frameworks.Escribiremos una biblioteca que almacene en caché y actualice datos, y admita relaciones, ordenación y filtrado.En lugar de obtener datos directamente, funcionará con datos obtenidos de forma asíncrona, incluidos los datos obtenidos después de la representación inicial. Los datos obtenidos y actualizados a través de web sockets también funcionarán bien.Todas estas características serán reactivas, por supuesto.Imagina que filtras tus datos por su título y luego actualizas el título de un registro para que coincida con el filtro: cualquier resultado que dependa de los datos filtrados se actualizará para reflejar el filtro actualizado.En 90 minutos, construirás una increíble biblioteca de datos reactiva y aprenderás una nueva herramienta poderosa para construir sistemas reactivos. La mejor parte: la biblioteca funciona en cualquier framework, incluso si no piensas en (o dependes de) ningún framework al construirla.
Tabla de contenidos- Almacenar un registro obtenido en una celda- Almacenar múltiples registros en un Mapa reactivo- La iteración reactiva es una iteración normal- El filtrado reactivo es un filtrado normal- Obtener más registros y actualizar el Mapa- La ordenación reactiva es una ordenación normal (¿se está volviendo un poco repetitivo?)- Modelar la invalidación de la caché como datos- Bonus: relaciones reactivas