Para esto también tengo un par de ejemplos. Por ejemplo, hay algunas bibliotecas por ahí que registran oyentes de eventos o suscriptores a alguna solución de gestión de estado y lo hacen durante el proceso de renderizado. Así que aquí tenemos este componente ficticio que crea un oyente durante la fase de renderizado y lo agrega directamente al objeto window. Ahora imagina que este componente nunca se desmonta, entonces este oyente quedará atrapado en el objeto window y nadie lo eliminará nunca, por lo que tenemos una fuga de memoria en nuestra aplicación. Afortunadamente, este problema no ocurre realmente con demasiada frecuencia en las aplicaciones.
Esto ocurre más en el código de bibliotecas y por lo tanto, cuando te adhieres a bibliotecas populares, no te encontrarás realmente con ese problema, pero aún es importante tenerlo en cuenta, que no mutemos el mundo exterior, no construyamos una conexión, no creemos sockets web y cosas así porque esto podría romperse cuando usamos características concurrentes. Sin embargo, aún debe ser posible de alguna manera hacer estas cosas, leer valores globales, mutar el mundo exterior, porque al final, nuestra aplicación está hecha para comunicarse con un servidor, comunicarse con el usuario, mostrar algún estado cambiante, por lo que debe haber algunas soluciones.
La primera opción es simplemente mover toda esta comunicación dentro de UseEffect porque UseEffect está hecho para que tengamos la construcción, para que podamos hacer una conexión con un oyente de eventos y cosas así, y tenemos la limpieza, por lo que simplemente devolvemos otra función de limpieza desde UseEffect y podemos limpiar si creamos algunas conexiones, agregamos un oyente de eventos y luego lo eliminamos nuevamente cuando el componente se desmonta. Y dado que siempre tenemos esta garantía de que siempre habrá una limpieza después de la llamada a UseEffect, es seguro hacer algo así dentro de UseEffect. Así que siempre tenemos este patrón en el que tienes una variable de estado dentro de tu componente, lees desde el servidor dentro de UseEffect, actualizas la variable de estado, y luego estás listo. El problema con eso es que durante la primera fase de reconciliación, el efecto aún no se ha llamado, por lo que cuando necesites mostrar algo desde la llamada a UseEffect, debes hacer la primera fase de reconciliación sin este valor porque solo estará presente en la segunda fase cuando el estado se haya actualizado.
La segunda opción es elegir una biblioteca que se ajuste a tu caso de uso. Si eliges React Query para comunicarte con el servidor, si eliges algo como Redux Toolkit para manejar tus soluciones de gestión de estado, puedes confiar en las bibliotecas populares que ya son seguras para el modo concurrente porque el equipo de React ha estado trabajando muy de cerca con los mantenedores en este proceso de RFC para que estas bibliotecas ya sean seguras para el modo concurrente. Y la tercera opción es si realmente quieres manejar tu propia solución es usar useSyncExternalStore. Este es un gancho que React nos proporciona que podemos usar para sincronizar nuestra aplicación con algunos datos externos. Para eso, primero debes definir una función de suscripción, pero nuevamente tienes esta noción de construcción, un constructor, por así decirlo, y una limpieza donde debes garantizar que siempre se ejecutarán en pares. Entonces aquí, por ejemplo, agregamos un EventListener al evento global de cambio de tamaño y nos aseguramos de eliminarlo nuevamente una vez que este proceso de sincronización sea limpiado por React. Después de hacer eso, podemos construir un gancho personalizado, use windowWidth, por ejemplo, y usar el gancho useSyncExternalStore donde pasamos nuestra función de suscripción como primer argumento, y el segundo argumento es el valor que lee desde el mundo exterior. Y ahora React puede estar absolutamente seguro de controlar cuándo se llama esta función de lectura para que React pueda estar seguro de que este valor nunca cambia durante un proceso de reconciliación para que la interfaz de usuario siempre se mantenga consistente. De esta manera, podemos usar nuestro gancho personalizado, use windowWidth, donde queramos en nuestra aplicación, y podemos usar el valor durante la representación inicial de nuestro componente y estar seguros de que durante las actualizaciones, también se mantendrá actualizado y no introducirá problemas de desgarro. Eso significa que cuando usamos una de esas tres opciones, podemos relajarnos y dejar que React haga su trabajo porque el equipo de React diseñó React de tal manera que vivimos por encima de este nivel de abstracción. Entonces, en un mundo ideal, nunca nos preguntaríamos cuántas veces se llaman nuestras fases de reconciliación porque React podría tomar algunas decisiones en el futuro para llamarlas más a menudo, llamarlas menos a menudo, omitir algunas o volver a llamarlas. Si React puede confiar en que estas funciones son puras, entonces React puede decidir estas cosas por nosotros y puede hacer optimizaciones sin que nuestro código se rompa. Entonces, con estas suposiciones, ahora es posible volver a relajarse y mantenerse seguro en el mundo concurrente de React. Gracias por escuchar. Muchas gracias. Gracias. Gracias. Muchas gracias. Si quieres unirte aquí, tenemos algunas preguntas.
Comments