dice que: "Cada vez que nuestro componente se renderiza, se llama a nuestro efecto, agregando otro detector de eventos. Con solo unos pocos clics y re-procesadores, ¡hemos adjuntado muchos detectores de eventos al DOM! Necesitamos limpiar después ¡Nosotros mismos!".
entonces, por cada clic, el conteo va de 1 a 3 a 7 en lugar de incrementarse en 1. No entiendo cómo se conectaron tantos detectores de eventos y cómo afecta esto al conteo total.
import React, { useState, useEffect } from 'react'; export default function Counter() { const [clickCount, setClickCount] = useState(0); const increment = () => { setClickCount(prev => prev + 1); }; useEffect(() => { document.addEventListener('mousedown', increment); }) return ( <h1>Document Clicks: {clickCount}</h1> ); }Está agregando un oyente al documento en sí , por lo que debe eliminarlo cuando se desmonta el componente.
Y necesita agregar una matriz de dependencia vacía para no agregar un nuevo oyente en cada renderizado
Y necesita envolver increment en un useCallback o usar una función de incremento diferente en el useEffect :
import React, { useState, useEffect } from 'react'; export default function Counter() { const [clickCount, setClickCount] = useState(0); const increment = useCallback(() => { setClickCount(prev => prev + 1); }, [setClickCount]); useEffect(() => { document.addEventListener('mousedown', increment); return () => document.removeEventListener('mousedown', increment); }, []) return ( <h1>Document Clicks: {clickCount}</h1> ); }Sin usar una matriz de dependencias, cada cambio activará su useEffect para que se ejecute nuevamente.
Entonces, cada renderizado, cada cambio de estado hará que crees otro eventListener .
Hablemos de la variante useEffect :
useEffect(() => { // invoking on every re-render }) useEffect(() => { // invoking on component did mount (once) }, []) useEffect(() => { // invoking on component did mount and with every change on counter }, [counter]) Además, debe eliminar su eventLinstener en el desmontaje del componente:
useEffect(() => { document.addEventListener('mousedown', increment); return () => document.removeEventListener('mousedown', increment); }, []) Como se mencionó con Samathingamajig en las respuestas, puede usar una forma optimizada de definir su función de increment con useCallback .
Con la implementación actual, su método increment se redefinirá cada vez (con cada cambio y renderizado), pero al usar useCallback se redefinirá solo cuando la matriz de dependencias de useCallback tenga cambios.
import React, {useEffect, useCallback} from 'react'; // rest of the codes ... const increment = useCallback(() => { setClickCount(prevState => prevState + 1); }, [setClickCount]);