Cuando hago clic en el botón de volver a renderizar, cambia este valor de estado global. Simplemente sigo haciendo clic hasta que todo termine con el renderizado. Puedes ver que React renderizó nuestro componente con el estado inicial y solo después de este proceso de reconciliación manejó mis eventos e incrementó el estado global, que es simplemente una variable global dentro de mi aplicación. También puedes ver que el estado en nuestro componente, en la interfaz de usuario, todavía representa el estado desde el inicio del proceso.
Durante esta reconciliación, React toma una instantánea dentro de esos elementos JSX y luego, cuando termina, confirma esas instantáneas en el DOM. Entonces, sin importar cuál sea el valor actual, confirma la instantánea desde el momento en que se ejecutó la reconciliación.
Ahora cambiemos a la actualización de baja prioridad. Está utilizando react-use-start-transition, como quizás ya hayas visto en otras charlas, para programar una actualización de baja prioridad. Ahora hagamos clic en volver a renderizar de baja prioridad y luego en cambiar el estado global nuevamente. Como quizás hayas visto, después de que el primer componente termine de renderizarse, React lo cede al navegador y el navegador decide que ahora necesita manejar esos clics de eventos. Llama a mi función que simplemente registra en la consola y cambia el valor de la variable, luego vuelve al navegador al bucle de eventos y el bucle de eventos decide que ahora React vuelve a tomar el control y continúa con el renderizado.
Esto sucede entre cada componente durante el proceso de renderizado, pero como ya puedes ver entre el componente 2 y 3, el bucle de eventos decide nuevamente darle a React la opción de hacer algo y no al controlador de eventos. Entonces, es un poco no determinista lo que está haciendo el navegador en segundo plano. A veces, los registros de la consola también aparecerían entre estos dos o solo aquí. Pero como puedes ver en nuestro caso, entre el componente 1 y 2, ocurrió el cambio en la variable. El primer componente se renderizó con el estado 25, el segundo se renderizó con 28 y el tercero también se renderizó con 28. Entonces, ahora puedes ver que el proceso de reconciliación ya no es estrictamente atómico en una aplicación moderna de React porque no sabemos si alguien más arriba en el árbol está utilizando esas características concurrentes y nos presenta esas fases de reconciliación que se dividen en el tiempo.
Y como puedes ver, esto conduce a problemas. Nuestro primer componente muestra el 25 y el segundo y tercer componente muestran el 28. Ahora tenemos este desgarro en nuestra aplicación. Una parte de nuestra aplicación muestra una instantánea en un momento determinado y las otras partes de la aplicación muestran otra instantánea en un momento determinado. Esto, por supuesto, no es lo que queremos.
Entonces, eso significa que necesitamos hacer para evitar este desgarro desagradable dentro de nuestras aplicaciones. Necesitamos dejar de leer valores que podrían cambiar fuera del mundo de React. En nuestro caso, esto era una simple variable global y leímos el valor de la variable y lo cambiamos en algún controlador de eventos. Si eso fuera una constante, estaría totalmente bien porque una constante nunca puede cambiar y luego podemos usar esa constante durante el renderizado. Pero necesitamos dejar de leer valores que podrían cambiar fuera de React. Por ejemplo, una variable local o almacenamiento local porque cualquiera puede escribir en el almacenamiento local o el valor actual de una propiedad de referencia porque esas referencias se hacen explícitamente para que tengas objetos que puedas mutar y restablecer fuera del mundo de React sin que React sepa que algo ha cambiado. Entonces, React no sabe que necesita volver a renderizar, no sabe que necesita abortar este nuevo proceso de renderizado concurrente y mostrará un estado inconsistente en tus interfaces de usuario en los peores casos. Y esto también significa que estás escribiendo tu propio Redux y líneas de moda, por ejemplo, que debes tener mucho cuidado de cómo lo conectas a tus componentes porque si simplemente llamas a getState() durante el proceso de renderizado, es el mismo problema.
Comments