Tengo un campo de entrada en React, en este campo de entrada el usuario está escribiendo un mensaje. Quiero, cuando el usuario comience a escribir, llamar a una función solo una vez. Probé una solución, pero está llamando a la función una y otra vez.
export default function App() { let typingTimer; //timer identifier let doneTypingInterval = 5000; let myInput = document.getElementById("input-text"); //on keyup, start the countdown if (myInput) { myInput.addEventListener("keyup", () => { clearTimeout(typingTimer); if (myInput.value) { typingTimer = setTimeout(doneTyping, doneTypingInterval); } }); } //user is "finished typing," do something function doneTyping() { console.log("done"); } return ( <div className="App"> <h1>Hello CodeSandbox</h1> <form> <input type="search" id="input-text" placeholder="Start typing...." /> </form> </div> ); } El código anterior llama a doneTyping después de 5 segundos, pero cinco veces. Quiero llamar solo una vez, y lo mismo cuando el usuario deja de escribir.
Estoy bastante seguro de que es un problema de cierre. este ejemplo de código funciona bien para restablecer el temporizador.
HTML:
<input type="button" id="test">JS:
let timer; document.getElementById('test').addEventListener('click', () => { clearTimeout(timer); timer = setTimeout(callback, 1000); }) function callback() { console.log('called'); }Quieres usar algo como Debounce .
Aquí hay un ejemplo de trabajo basado en su código en Codesandbox .
Nota: Verifique la consola.
import React, { useRef } from "react"; const DEBOUNCE_THRESHOLD = 500; export default function App() { const timeoutHandler = useRef(null); const handleChange = (event) => { if (timeoutHandler.current) { clearTimeout(timeoutHandler.current); } timeoutHandler.current = setTimeout(() => { console.log(event.target.value); }, DEBOUNCE_THRESHOLD); }; return ( <div className="App"> <h1>Hello CodeSandbox</h1> <form> <input type="search" onChange={handleChange} id="input-text" placeholder="Start typing...." /> </form> </div> ); } <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>