Tengo un componente React simple que se supone que debe consolar. Registrar un texto ficticio cuando se procesa el componente. He leído algunos artículos sobre el renderizado y supongo que el renderizado ocurre al mismo tiempo que se invoca el componente, es decir, el renderizado no es posible sin invocar/ejecutar la función del componente a priori .
Por lo tanto, la cantidad de registros de la consola en este caso debe ser 2 para cada uno: una vez cuando el componente se procesa inicialmente, y la segunda vez cuando hago clic en el botón y estoy configurado en 2. La próxima vez que React debería poder detectar ese estado es en realidad no es lo mismo y no vuelve a renderizar el componente.
Pero recibo "Hello from invoking" (que no está en efecto de uso sino en el cuerpo del componente) tres veces, una vez cuando el componente se procesa inicialmente y dos veces cuando hago clic en el botón. Este componente seguramente se representa solo dos veces, entonces, ¿de dónde vino ese tercer archivo console.log? ¿Es posible que se invoque la función del componente, pero no se vuelva a renderizar? Por el contrario, "Hola desde la representación" se registra dos veces como supongo.
import { useEffect, useState } from "react"; const DummyComponent = (props) => { const [i, setI] = useState(0); useEffect(() => { console.log("hello from rendering!"); }); console.log("hello from invoking!"); return ( <div onClick={() => setI(2)}}> Hello </div> ); }; export default DummyComponent;Cuando onClick llama a setI , esto provoca un cambio en el estado y se activa una actualización . Esto llamará a los métodos de ciclo de vida asociados con una actualización .
- getDerivedStateFromProps estático()
- deberíaActualizarComponente()
- prestar()
- getSnapshotBeforeUpdate()
- componenteHizoActualizar()
El enlace useEffect se llama durante el componentDidUpdate() (así como el componentDidMount ), mientras que el archivo console.log fuera del useEffect se llamará durante el render() .
¡Eso significa que deberíamos esperar ver 1 hello from rendering! y 1 hello from invoking! cuando actualizamos o cuando hacemos clic en el div "Hola".
En este ejemplo de codesandbox , puede ver que obtenemos el comportamiento esperado de un solo console.log de cada uno.
Ahora, en este ejemplo de codesandbox , estamos usando StrictMode , y puede ver que cuando hacemos clic en "Hola", ¡estamos viendo hello from rendering! 1 vez, pero estamos viendo hello from invoking! ¡2 veces!
StrictMode se habilitó agregando una etiqueta <StrictMode> a index.js
root.render( <StrictMode> <App /> </StrictMode> ); Parece que el comportamiento que está describiendo proviene del uso de StrictMode .
Esto sucede porque StrictMode intencionalmente invoca dos veces las siguientes funciones:
- Constructor de componentes de clase, renderizar y métodos shouldComponentUpdate
- Componente de clase método estático getDerivedStateFromProps
- Cuerpos de componentes de función
- Funciones de actualización de estado (el primer argumento de setState)
- Funciones pasadas a useState, useMemo o useReducer
Por lo tanto, vemos que la función de render ocurre 2 veces y obtenemos los 2 console.logs .