Estaba estudiando los ganchos de React e insertando algunos registros de consola en el código para comprender mejor el flujo de procesamiento. Luego comencé a simular los efectos de setState enviando el mismo valor para ver si React lo renderizaba nuevamente.
import { useState } from "react"; function ManComponent() { /* States */ const [shirt, setShirt] = useState("Blue Shirt"); console.log("Rendering man with "+shirt); /* Actions */ const changeShirt = (newShirt) => { console.log("[Man] Changing shirt from "+shirt+" to "+newShirt); setShirt(newShirt); }; return ( <div> <p>The man is using: {shirt}</p> <div> <button onClick={() => changeShirt("Red Shirt")}>Change to red shirt</button> <button onClick={() => changeShirt("Blue Shirt")}>Change to blue shirt</button> </div> </div> ); } export default function App() { console.log("Rendering app"); return ( <ManComponent /> ); }Si hago clic tres veces en "Cambiar a camisa roja", aparecen dos registros que indican que el componente se está procesando. Debería ser solo uno, ya que cambié el valor solo una vez, ¿verdad?
Mi problema es entender por qué el componente se representa dos veces si el estado solo cambió una vez.
PD: Traté de eliminar el modo estricto y no tuvo ningún efecto. Estoy usando la versión React 17, por cierto.
La documentación de React aborda exactamente este comportamiento en la API de useState .
Salir de una actualización de estado
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 React aún puede necesitar 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.
El modo estricto fue una buena suposición, ya que solía desencadenar registros duplicados en el ciclo de procesamiento antes de React 17, aunque se actualizó para silenciar estos registros duplicados para evitar confusiones .
A partir de React 17, React modifica automáticamente los métodos de la consola como
console.log()para silenciar los registros en la segunda llamada a las funciones del ciclo de vida. Sin embargo, puede causar un comportamiento no deseado en ciertos casos en los que se puede utilizar una solución alternativa.
... lo que causó confusión adicional , lo que llevó a otra actualización sobre ese comportamiento de registro de modo estricto (que aún no se ha publicado, creo).
La solución alternativa mencionada en la cita anterior para depurar la representación en modo estricto con registros es mantener una copia del alcance del módulo de la función de registro.
const log = console.log; const App = () => { log('Will not be silenced by React'); return //... };