En el siguiente código tengo un problema.
Estaba tratando de implementar comportamientos de doubleClick y el gancho de estado para que los cambios booleanos lo activen. El problema es que, aunque se activa la función handleDoubleClick , setAllowSingleClick no cambia el valor a falso, por lo que, de todos modos, se activa la función handleClick .
<div onClick={handleClick} onDoubleClick={handleDoubleClick}> const CLICK_DELAY_TIME = 200; const [allowSingleClick, setAllowSingleClick] = useState(true); let timer = 0; const handleClick = () => { timer = setTimeout(() => { if (allowSingleClick) { doSMTH1(); } }, CLICK_DELAY_TIME); }; const handleDoubleClick = () => { clearTimeout(timer); setAllowSingleClick(false); doSMTH(); };no useState() en devoluciones de llamada anidadas. useRef() en su lugar.
useState() en sí mismo es solo una especie de gancho que devuelve valor y setter (funciona de forma asíncrona).
cuando se construye la función de devolución de llamada setTimeout(), el valor de la variable allowSingleClick se fija en la definición de la función de devolución de llamada (este fenómeno se conoce como cierre).
lo que useRef() devuelve es objeto: valor evaluado cuando se hace referencia a la propiedad .current .
código de ejemplo
import React from "react"; import { useRef } from "react"; function App() { const CLICK_DELAY_TIME = 200; const allowSingleClickRef = useRef(true); const doSMTH1 = () => console.log("!!!"); const doSMTH = () => console.log("???"); let timer = null; const handleClick = () => { timer = setTimeout(() => { if (allowSingleClickRef.current) { doSMTH1(); } }, CLICK_DELAY_TIME); }; const handleDoubleClick = () => { clearTimeout(timer); allowSingleClickRef.current = false; doSMTH(); }; return ( <div style={{ backgroundColor: "red", width: "100vw", height: "100vh" }} onClick={handleClick} onDoubleClick={handleDoubleClick} /> ); } export default App;Más lecturas: Haciendo setInterval Declarative con React Hooks por Dan Abramov