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

React中async/await结合debounce函数的用法及代码问题排查

问题分析与修复

核心问题1:防抖函数的apply调用错误

你的debounce函数里,setTimeout内的fn.apply(this, ...args)写法有误。apply的第二个参数要求是数组,但...args会把传入的数组参数展开成单个值,导致apply接收的不是合法参数,最终函数执行失败,API请求自然无法发起。

正确写法应该是:

timeoutId = setTimeout(() => fn.apply(this, args), delay);
// 或者更简洁的箭头函数写法:
timeoutId = setTimeout(() => fn(...args), delay);

核心问题2:用useMemo缓存防抖函数不合适

useMemo的定位是缓存计算结果值,虽然这里也能得到防抖函数,但语义完全不对——React专门提供了useCallback来缓存函数,用它才是正确的姿势。

额外问题:React合成事件回收导致取值失败

React的合成事件对象会被内部复用,当防抖延迟触发时,原事件对象已经被回收,evt.target.value会无法获取到正确的输入值。所以要在onChange回调里先把输入值提取出来,再传给防抖函数。


修复后的完整代码

const { useState, useCallback } = React;

function debounce(fn, delay) {
  let timeoutId;
  return (...args) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  }
}

const getApi = (terms) => `https://www.reddit.com/search.json?q=${terms}`;
const Search = () => {
  const DELAY = 500;
  const [text, setText] = useState("");
  const [list, setList] = useState([]);

  // 用useCallback缓存防抖函数
  const fetchData = useCallback(debounce(async(terms) => {
    if (!terms) {
      setList([]);
      return;
    }
    const res = await fetch(getApi(terms));
    const {data} = await res.json();
    setList(data.children.map(d => d.data.title));
  }, DELAY), []);

  return (
    <div>
      <form className="bg-gray-200 p-5">
        <input
          type="text"
          name="text"
          placeholder="search users..."
          value={text}
          onChange={(e) => {
            const value = e.target.value;
            setText(value);
            fetchData(value); // 传入提取好的value,而非事件对象
          }}
          className="bg-white p-2 w-3/4 outline-none"
        />
      </form>
      <ul>
        {list.map((title, index) => <li key={index}>{title}</li>)}
      </ul>
    </div>
  );
};

ReactDOM.render(<Search />, document.getElementById("app"));

额外补充了两点优化:

  1. 增加空值判断,避免输入为空时发起无效API请求
  2. 给列表项添加key属性,符合React列表渲染的规范

内容的提问来源于stack exchange,提问作者Chuang Fu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 00:01:14