Estate atento ya que en esta división hallarás la solución que buscas.
Solución:
Voy a hacer todo lo posible para explicar (o explicar) lo que está sucediendo. También estoy haciendo dos suposiciones, en el punto 7 y el punto 10.
- Montajes de componentes de aplicaciones.
useEffect
se llama después del montaje.useEffect
‘salvará’ el estado inicial y asícounter
será 0 siempre que se haga referencia en su interior.- El bucle se ejecuta 3 veces. Cada iteración
setCount
se llama para actualizar el recuento y el registro de la consola registra el contador que, según la versión ‘almacenada’, es 0. Por lo tanto, el número 0 se registra 3 veces en la consola. Debido a que el estado ha cambiado (0 -> 1, 1 -> 2, 2 -> 3) React se establece como una bandera o algo para decirse a sí mismo que recuerde volver a renderizar. - React no ha vuelto a renderizar nada durante la ejecución de
useEffect
y en su lugar espera hasta eluseEffect
se hace para volver a renderizar. - Una vez el
useEffect
hecho, React recuerda que el estado decounter
ha cambiado durante su ejecución, por lo que volverá a renderizar la aplicación. - La aplicación vuelve a renderizar y el
useCounter
se vuelve a llamar. Nótese aquí que no se pasan parámetros aluseCounter
gancho personalizado.
Suposición:Yo tampoco sabía esto, pero creo que el parámetro predeterminado parece haber sido creado nuevamente, o al menos de una manera que hace que React piense que es nuevo. Y así porque elarr
se ve como nuevo, eluseEffect
gancho se ejecutará de nuevo. Esta es la única razón por la que puedo explicar eluseEffect
corriendo por segunda vez. - Durante la segunda carrera de
useEffect
loscounter
tendrá el valor de 3. El registro de la consola registrará el número 3 tres veces como se esperaba. - Después de la
useEffect
se ejecutó por segunda vez React descubrió que el contador cambió durante la ejecución (3 -> 1, 1 -> 2, 2 -> 3) y, por lo tanto, la aplicación se volverá a procesar causando el tercer registro de ‘renderización’. - Suposición:porque el estado interno del
useCounter
gancho no cambió entre este render y el anterior desde el punto de vista de la aplicación, no ejecuta código dentro de él y por lo tanto eluseEffect
no se llama una tercera vez. Entonces, el primer renderizado de la aplicación siempre ejecutará el código de gancho. El segundo, la aplicación vio que el estado interno del gancho cambió sucounter
de 0 a 3 y, por lo tanto, decide volver a ejecutarlo, y la tercera vez que la aplicación ve que el estado interno era 3 y sigue siendo 3, por lo que decide no volver a ejecutarlo. Esa es la mejor razón que se me ocurre para que el gancho no vuelva a funcionar. Puede colocar un registro dentro del gancho para ver que, de hecho, no se ejecuta por tercera vez.
Esto es lo que veo que sucede, espero que esto lo haya aclarado un poco.
Encontré una explicación para el tercer renderizado en los documentos de reacción. Creo que esto aclara por qué react hace el tercer render sin aplicar el efecto:
Si actualiza un State Hook al mismo valor que el estado actual, React se rescatará sin renderizar a los niños ni disparar efectos. (React usa el algoritmo de comparación Object.is).
Tenga en cuenta que es posible que React aún necesite renderizar ese componente específico nuevamente antes de rescatar. Eso no debería ser una preocupación porque React no profundizará innecesariamente en el árbol. Si está haciendo cálculos costosos mientras renderiza, puede optimizarlos con useMemo.
Parece que useState y useReducer comparten esta lógica de rescate.
setState y ganchos similares no vuelven a representar inmediatamente su componente. Pueden procesar por lotes o diferir la actualización hasta más tarde. Entonces obtienes solo un renderizado después del último setCount
con counter === 3
.
Obtienes el renderizado inicial con counter === 0
y dos renders adicionales con counter === 3
. No estoy seguro de por qué no va a un bucle infinito. arr = [1, 2, 3]
deberia crear una nueva array en cada llamada y disparador useEffect
:
- conjuntos de renderizado iniciales
counter
para0
useEffect
registros0
tres veces, conjuntoscounter
para3
y activa un renderizado- primera renderización con
counter === 3
useEffect
registros3
tres veces, conjuntoscounter
para3
y ???
React debería detenerse aquí o ir a un bucle infinito desde el paso 3.
Si conservas algún reparo o forma de arreglar nuestro artículo te recomendamos escribir una interpretación y con deseo lo analizaremos.