Tengo un componente React simple y establezco el mismo valor cada vez que hago clic en el botón:
import React, { useState } from 'react'; import './style.css'; let data = { title: 'ABC' }; export default function App() { const [foo, setFoo] = useState(); console.log('Rendered'); return ( <div> <button onClick={() => setFoo(data)}>Set Data</button> <h1>Data: {JSON.stringify(foo)}</h1> </div> ); }Pero los renders son un poco extraños porque al hacer clic en el segundo botón, React renderiza el componente, pero configuro el mismo valor. ¿Por qué React vuelve a renderizar el componente aunque configuro el mismo valor?
La pregunta es por qué el componente se procesa aunque el nuevo estado es igual al estado anterior (comparación superficial)
// On second button click const prevState = data // State trigger setFoo(data) // Same state, it doesn't triggers a render data === prevStatePor lo tanto, el componente no activó el procesamiento debido al cambio de estado.
Pero sucedió debido a otra razón , como se menciona en los documentos "entre líneas" en la sección de actualización de estado de la API de ganchos :
Tenga en cuenta que es posible que React aún necesite renderizar ese componente específico nuevamente antes de rescatar.
A diferencia del componente de clase, para los componentes de función, después de establecer el mismo estado como en nuestro caso, a veces , React necesitará otro procesamiento para validar su igualdad. Su desafortunado caso extremo .
Pero no debería considerarlo como un "problema de rendimiento" ya que no afecta el árbol React.Node , no continuará en el proceso de reconciliación si el estado no cambió. Incluso no hará llamadas de ganchos innecesarias.
Lo mismo ocurre aquí, hay otro render para rescatar, otro registro de "A".
Aunque hay un renderizado de "rescate", observe que useEffect no se ejecuta.
import React, { useEffect } from "react"; import ReactDOM from "react-dom"; const App = () => { const [state, setState] = React.useState(0); useEffect(() => { console.log("B"); }); console.log("A"); return ( <> <h1>{state}</h1> <button onClick={() => setState(42)}>Click</button> </> ); }; ReactDOM.render(<App />, document.getElementById("root")); Si se pregunta sobre el orden de los registros ("¿Por qué 'A' se registró antes que 'B'?"), Intente profundizar en otra pregunta: Reaccionar useEffect en profundidad / use of useEffect ?
En el componente funcional, un componente no se vuelve a representar si tiene el mismo valor, es decir, un valor que pasa la comparación ===:
const [state, setState] = useState({}); ... setState(state => state); // no re-renderDe lo contrario, se vuelve a renderizar un componente:
setState(state => ({...state})); // re-renderComo ya se comentó, puede ser "reprocesado" por reaccionar, pero es probable que el DOM no cambie.