如何在数据变化时让useEffect延迟N秒触发?
实现输入防抖触发请求
你需要给这个逻辑加上**防抖(Debounce)**处理,核心思路是每次输入变化时先取消之前的延迟任务,重新计时,只有当输入停止N秒后才执行请求。具体实现如下:
import { useState, useEffect, useRef } from 'react'; // 组件内代码 const [query, setQuery] = useState<string>(''); // 用useRef保存定时器ID,避免每次重渲染丢失引用 const debounceTimerRef = useRef<NodeJS.Timeout | null>(null); useEffect(() => { // 每次query变化时,先清除之前的定时器 if (debounceTimerRef.current) { clearTimeout(debounceTimerRef.current); } // 设置新的定时器,N秒后执行请求(示例为1000毫秒=1秒) const timer = setTimeout(() => { dispatch(postQuery(query)); }, 1000); // 保存定时器ID到ref debounceTimerRef.current = timer; // 组件卸载或query变化前,清除定时器避免内存泄漏 return () => { if (debounceTimerRef.current) { clearTimeout(debounceTimerRef.current); } }; }, [query, dispatch]); // 依赖加入dispatch,避免闭包问题与ESLint警告 <input value={query} onChange={e => setQuery(e.currentTarget.value)} />
关键细节说明:
- useRef存定时器ID:useRef的
.current属性在组件生命周期内保持稳定,不会随重渲染重置,适合存储跨渲染周期的变量。 - 清理旧定时器:确保只有最后一次输入停止等待N秒后才触发请求,避免频繁触发无效请求。
- 卸载时清理:防止组件卸载后定时器仍执行,引发内存泄漏或无效状态更新。
如果需要复用防抖逻辑,可以封装成自定义Hook:
function useDebounce<T>(value: T, delay: number): T { const [debouncedValue, setDebouncedValue] = useState<T>(value); useEffect(() => { const timer = setTimeout(() => { setDebouncedValue(value); }, delay); return () => clearTimeout(timer); }, [value, delay]); return debouncedValue; } // 组件内使用 const debouncedQuery = useDebounce(query, 1000); useEffect(() => { dispatch(postQuery(debouncedQuery)); }, [debouncedQuery, dispatch]);
这样能将防抖逻辑与业务逻辑分离,代码更简洁易维护。
内容的提问来源于stack exchange,提问作者middleStackoverflower
相关产品推荐
相关产品推荐

