You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:02:27