De React Docs, lo que aprendí es que el componente se volverá a renderizar solo si hay un cambio en el valor de un estado.
Por ejemplo
import React, { useState } from "react"; export default function Counter() { const [count, setCount] = useState(0); console.log("I am rendering"); const handleButtonClick = () => { setCount(0); }; return ( <> <button onClick={handleButtonClick}>Increment</button> Count value is: {count} </> ); }
El mensaje I am rendering
se imprime solo una vez , incluso si hacemos clic en el botón porque la función setCount
está configurando el valor en 0
, que es el valor actual de count
Dado que no hay cambios en el valor presente y futuro, el Componente no se vuelve a representar.
Sin embargo, no se observa un comportamiento similar cuando agregamos una línea adicional setCount(1)
antes de setCount(0)
import React, { useState } from "react"; export default function Counter() { const [count, setCount] = useState(0); console.log("I am rendering"); const handleButtonClick = () => { setCount(1); //this line has been added extra setCount(0); }; return ( <> <button onClick={handleButtonClick}>Increment</button> Count value is: {count} </> ); }
En principio, no hay cambio en la salida del valor de count
final. Sin embargo, si hacemos clic en el botón, el componente vuelve a mostrar e imprime el mensaje I am rendering
No pude encontrar una explicación para este comportamiento. ¿Es este comportamiento en las líneas esperadas?.
¿No debería volver a renderizarse el componente solo cuando el valor final del estado es diferente del valor actual?
A veces, Reacts necesita otra fase de renderizado para decidir si necesita un rescate. Por cierto, cuando decimos "rescate" significa rescatar el proceso de reconciliación .
Observe la documentación sobre el rescate de una actualización de estado :
Tenga en cuenta que React aún puede necesitar renderizar ese componente específico nuevamente antes de rescatar .
Aquí hay otro ejemplo de tal caso que demuestra la idea:
import React, { useEffect } from "react"; import ReactDOM from "react-dom"; const App = () => { const [state, setState] = React.useState(0); useEffect(() => { console.log("B"); }, [state]); console.log("A"); return ( <> <h1>{state}</h1> <button onClick={() => setState(42)}>Click</button> </> ); }; ReactDOM.render(<App />, document.getElementById("root"));
Observa los siguientes registros y sus explicaciones:
A // First render B // Mount A // State change from 0 -> 42, triggers render B // useEffect dep array change, triggers callback A // **Our issue**, React needs another render
El valor cambia cuando presiona el botón. Primero, cambia a 1 y luego a 0, pero se ejecuta tan rápido que no se puede ver.
para ver esto, puede agregar un setTimeout
const handleButtonClick = () => { setCount(1); //this line has been added extra setTimeout(() => { setCount(0); }, 500); };