使用useMemo和useCallback实现防抖时返回值为undefined的问题
问题原因及解决方案
为什么返回undefined?
你的防抖函数返回的是一个异步触发的函数:调用p()时,只是启动了定时器,真正执行filterList是在400ms后,而p()本身没有同步返回值,所以自然得到undefined。
另外,useMemo的使用逻辑完全错误:useMemo是用来同步缓存计算结果的,它不适合处理防抖这种异步延迟逻辑,而且你的useMemo依赖只有debouncedFn,userList或filterValue变化时不会重新计算,根本无法更新过滤结果。
正确实现方式
防抖应该用在触发过滤的时机(比如输入框输入、筛选条件变化),通过状态来保存过滤后的结果。
步骤1:优化防抖函数(类型更严谨)
const debouncedFn = React.useCallback((fn: (...args: any[]) => void, delay: number) => { let timer: NodeJS.Timeout | null = null; return (...args: any[]) => { clearTimeout(timer!); timer = setTimeout(() => fn(...args), delay); }; }, []);
步骤2:用状态保存过滤结果,绑定防抖到触发时机
假设你是通过输入框的filterValue变化触发过滤:
const [filterValue, setFilterValue] = React.useState(''); const [filteredItems, setFilteredItems] = React.useState(userList); // 生成防抖后的过滤函数 const debouncedFilter = React.useMemo(() => { return debouncedFn(() => { // 执行过滤并更新状态 const result = userList.filter(x => x.advertiser_name.includes(filterValue)); setFilteredItems(result); }, 400); }, [userList, filterValue, debouncedFn]); // 当筛选条件变化时,触发防抖过滤 React.useEffect(() => { debouncedFilter(); }, [filterValue, debouncedFilter]);
或者直接绑定到输入框事件
如果是输入框触发,也可以直接把防抖逻辑写在onChange里:
<input value={filterValue} onChange={(e) => { setFilterValue(e.target.value); debouncedFilter(); }} />
关键注意点
- 防抖的核心是延迟执行触发动作,而不是延迟返回计算结果,所以不能指望通过防抖函数同步拿到过滤后的数据,必须用状态来存储异步计算的结果。
useMemo的依赖要包含所有影响计算的变量(userList、filterValue),否则过滤结果不会随数据变化更新。
内容的提问来源于stack exchange,提问作者Aayushi
相关产品推荐
相关产品推荐

