Supongamos que existe el siguiente componente simple. Cuando hago clic en el botón, el mensaje cambiará a Clicked durante 1 segundo y luego volverá a - . Sin embargo, cuando envío spam al botón, quiero que se haga clic en el título, pero debería Clicked a - después del último clic en el botón. Básicamente, quiero que cada clic amplíe el tiempo de espera.
Si se tratara de una función JS simple, simplemente borraría el intervalo después de cada clic y establecería otro tiempo de espera. Sin embargo, no estoy seguro de cómo lograr el mismo resultado usando ganchos de reacción.
import ReactDOM from 'react-dom'; import {useEffect, useState} from 'react'; import './index.css'; const Test = () => { const [message, setMessage] = useState("-"); const buttonClick = () => { setMessage("Clicked"); } useEffect(() => { if(message !== "-") { const id = setTimeout(() => { console.log("Running Interval"); setMessage("-"); }, 1000); return () => { console.log("Clearing Interval"); clearTimeout(id); } } }, [message]); return ( <article> <header> {message} </header> <button onClick={buttonClick}>button</button> </article> ); }Coloque la ID de tiempo de espera en una referencia y luego puede llamar a clearTimeout al comienzo del controlador de clics.
const Test = () => { const [message, setMessage] = React.useState("-"); const timeoutIdRef = React.useRef(); const handleClick = () => { setMessage("Clicked"); clearTimeout(timeoutIdRef.current); timeoutIdRef.current = setTimeout(() => { setMessage("-"); }, 1000); }; // cleanup, if desired // React.useEffect(() => clearTimeout(timeoutIdRef.current), []); return ( <article> <header> {message} </header> <button onClick={handleClick}>button</button> </article> ); } ReactDOM.render(<Test />, document.querySelector('.react')); <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='react'></div>