const func = () => { const id = setTimeout(() => { //do something with an element }, 300); return id; }; useEffect(() => { const id = func(); return () => clearTimeout(id); }, [click]); Cuando hago clic demasiado rápido, que es el desencadenante de useEffect , podría hacer que la función pasada a setTimeout no se ejecute.
¿Cuál es el problema?
¿Es la siguiente solución alternativa igual de buena?
const func = () => { const id = setTimeout(() => { if (element is stilled defined) { // do something } }, 300); return id; }; useEffect(() => { func(); }, [click]);Si entiendo su código correctamente, parece que desea retrasar una función de devolución de llamada por algún delta. Sugiero usar una referencia React para rastrear una serie de temporizadores en ejecución. Cuando se invoca la función, agregue la nueva identificación de tiempo de espera a esta matriz, cuando expire el tiempo de espera, bórrela de la matriz. Use un useEffect onUnmount para limpiar cualquier tiempo de espera en ejecución.
const timeoutRef = useRef([]); const func = () => { const id = setTimeout(() => { //do something with an element dequeueCallback(id); }, 3000); enqueueCallback(id); }; const enqueueCallback = (id) => { timeoutRef.current.push(id); }; const dequeueCallback = (id) => { timeoutRef.current = timeoutRef.current.filter((el) => el !== id); }; useEffect(() => { // clear any running timeouts upon unmount return () => { timeoutRef.current.forEach(clearTimeout); }; }, []);Puede resolver este problema mediante la función de limpieza, la función de limpieza se activará cuando se active la reproducción del efecto, por lo que puede poner lo que debe suceder antes de cualquier acción, de modo que la solución sea simplemente esto:
useEffect(() => { console.log(myEvent); // You can add condtion here and above of cleaner const timer = setTimeout(() => { if(myEvent !== null){// Internal contion alert("HI MAN"); } }, 2000); return () => clearTimeout(timer);// This is important part }, [myEvent]);revisa este ejemplo:
import { useEffect, useState } from "react"; import "./styles.css"; export default function App() { const [myEvent, setMyEvent] = useState(null); useEffect(() => { console.log(myEvent); const timer = setTimeout(() => { if(myEvent !== null){ alert("HI MAN"); } }, 2000); return () => clearTimeout(timer); }, [myEvent]); return ( <div className="App"> <button onClick={() => { setMyEvent(Math.random); }}>test</button> </div> ); }Y esta esla demostración de URL .
Referencia de reacción: ganchos de reacción