Tengo la siguiente configuración en un componente de reacción donde he usado la función de rebote del paquete throttle-debounce para registrar el valor de entrada para la prueba (realmente llamando a una API para obtener datos).
import React, { useState, useRef } from 'react'; import debounce from 'throttle-debounce/debounce'; const MyComponent = () => { const [localSearchQuery, setLocalSearchQuery] = useState(''); const setSearchQueryInParams = debounce(2000, value => console.log(value)) const setSearchQuery = value => { setLocalSearchQuery(value); setSearchQueryInParams(value); }; return ( <> <Input value={localSearchQuery} onChange={setSearchQuery} />; </> ); }; Pero, no está funcionando como se esperaba. Si escribo hello en el cuadro de entrada, obtengo el siguiente resultado en la consola:
h he hel hell helloSin embargo, si envuelvo la función de rebote con useRef, funciona como se esperaba
const setSearchQueryInParams = useRef(debounce(2000, value => console.log(value))).current Input: hello Output in console: helloMi pregunta es, ¿por qué la función de rebote no funciona sin useRef y cómo funciona useRef aquí para obtener el resultado deseado?
Gracias por la ayuda.
Querrá usar useCallback , con una matriz de dependencia vacía, en lugar de useRef :
import React, { useState, useCallback } from 'react'; import debounce from 'throttle-debounce/debounce'; const MyComponent = () => { const [localSearchQuery, setLocalSearchQuery] = useState(''); const setSearchQueryInParams = useCallback(debounce(2000, value => console.log(value)), []); const setSearchQuery = value => { setLocalSearchQuery(value); setSearchQueryInParams(value); }; return ( <> <Input value={localSearchQuery} onChange={setSearchQuery} />; </> ); }; La razón es que llamar a debounce siempre devuelve una nueva función, por lo que debe almacenar esa función en las representaciones.
Sin eso, no tiene memoria de los setTimeout a los que llama internamente, por lo que no puede usarlos para eliminar el rebote correctamente.