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

React useState问题:useCallback防抖函数中状态值始终为空

问题分析与解决方案

核心问题:闭包导致防抖函数捕获旧状态

你的防抖函数始终拿到空数组,是因为闭包特性:debounceOnChangeScript 通过 useCallback 创建,依赖项为空数组,意味着它会一直使用组件初始渲染时的 inputArr 快照(也就是空数组)。后续状态更新后,防抖函数内部的 inputArr 并不会自动更新,始终指向初始值。

另外你的 getCheckedValues 里也有小问题:setInputArr 是异步操作,调用后立刻 console.log(inputArr) 也拿不到最新状态,因为当前渲染周期的 inputArr 还没更新。


代码修正步骤

1. 优化状态更新逻辑(避免依赖当前状态快照)

把直接依赖 inputArr 的更新改成函数式更新,确保每次都能拿到最新的前序状态,同时用 find 替代 filter(因为你只需要匹配单个对象):

const getCheckedValues = (e) => {
  if (e.target.checked) {
    const targetId = Number(e.target.id);
    const targetObj = tableData.find(obj => obj.id === targetId);
    if (targetObj) {
      // 函数式更新:prev 是当前最新的 inputArr 状态
      setInputArr(prev => [...prev, {
        id: targetObj.id,
        schemaName: targetObj.schemaName,
        tableName: targetObj.tableName,
        keys: targetObj.keys
      }]);
    }
  }
};

2. 解决防抖函数的闭包问题(两种可选方案)

方案一:调用防抖函数时传入最新状态

直接把当前最新的 inputArr 作为参数传给防抖函数,避免依赖闭包中的旧值:

// 重新定义防抖函数,接收当前状态作为参数
const debounceOnChangeScript = React.useCallback(debounce((value, id, currentInputArr) => {
  console.log('Inside onChangeScript');
  console.log(currentInputArr);
  currentInputArr.forEach(element => console.log(element));
}, 1000), []);

// 调用防抖函数时,传入最新的 inputArr
// 示例:比如在某个触发事件中调用
// debounceOnChangeScript(someValue, someId, inputArr);
方案二:用 useRef 保存最新状态

通过 useRef 同步状态的最新值,防抖函数直接读取 ref.current 获取最新数据:

// 创建 ref 同步 inputArr 的最新值
const inputArrRef = React.useRef(inputArr);

// 每次 inputArr 更新时,同步到 ref
React.useEffect(() => {
  inputArrRef.current = inputArr;
}, [inputArr]);

// 防抖函数读取 ref.current 获取最新状态
const debounceOnChangeScript = React.useCallback(debounce((value, id) => {
  console.log('Inside onChangeScript');
  console.log(inputArrRef.current);
  inputArrRef.current.forEach(element => console.log(element));
}, 1000), []);

内容的提问来源于stack exchange,提问作者Karthik Saxena

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:44:55