You need to enable JavaScript to run this app. React state hook更新后即使使用useEffect也无法正常存入数据库,存在延迟保存问题
优惠活动
大模型
产品
解决方案
定价
更多

React state hook更新后即使使用useEffect也无法正常存入数据库,存在延迟保存问题

问题根因

  • React中setState是异步操作,调用setDateEl、setValueEl、setUpdatedIncome后,当前渲染周期内拿到的state仍然是更新前的旧值,这是第一次操作无响应、第二次操作才保存上一次数据的核心原因。
  • 直接修改updatedIncome原数组的元素(updatedIncome[index] = incomeObject)属于直接变更state引用,可能导致React无法正确触发重渲染。
  • 没必要通过useEffect监听updatedIncome触发保存,完全可以在数据处理完成后直接调用保存逻辑,避免闭包捕获旧值的问题。

修复方案

首先删除监听updatedIncome的useEffect逻辑,按如下方式修改两个业务函数即可:

const handleIncome = () => {
  // 直接把表单值存在临时变量里,不依赖state的异步更新
  const newDate = document.querySelector('#IncomeDate').value;
  const newValue = document.querySelector('#IncomeValue').value;

  let incomeObject = {};
  incomeObject[
    format(parse(newDate, 'yyyy-MM', new Date()), 'yyyy-MM-dd')
  ] = reverseFormatNumber(newValue);

  const index = updatedIncome
    .map((key) => Object.keys(key)[0])
    .indexOf(Object.keys(incomeObject)[0]);

  let newUpdatedIncome;
  if (index !== -1) {
    // 先拷贝原数组再修改,不直接修改state的原数组
    newUpdatedIncome = [...updatedIncome];
    newUpdatedIncome[index] = incomeObject;
  } else {
    newUpdatedIncome = [...updatedIncome, incomeObject].sort(
      (a, b) => new Date(Object.keys(a)[0]) - new Date(Object.keys(b)[0])
    );
  }      
  // 直接用处理好的新数据调用保存接口,不用等state更新
  handleAddIncome({ incomes: newUpdatedIncome }, index);
  // 再更新本地state
  setDateEl(newDate);
  setValueEl(newValue);
  setUpdatedIncome(newUpdatedIncome);
  toggleAddIncome(null, true);
};
const handleAddIncome = async (incomesObj, index) => {
  const config = {
    headers: {
      'Content-Type': 'application/json',
    },
  };
  try {
    await axios.post(`/api/investments/${id}/incomes`, incomesObj, config);
    // 这里用传入的最新数据,不要用外层的旧updatedIncome避免闭包问题
    const currentIncomes = incomesObj.incomes;
    const dates = currentIncomes
      .filter((invest) => Object.values(invest)[0] !== null)
      .map((key) => Object.keys(key).map((date) => date))
      .flat()
      .map((data) => {
        let datePartes = data.split('-');
        return `${datePartes[2]}/${datePartes[1]}/${datePartes[0]}`;
      });

    const IncomesTemp = currentIncomes
      .filter((invest) => Object.values(invest)[0] !== null)
      .map((key) => Object.values(key)[0]);

    let temparray = [];
    for (let i = 0; i < IncomesTemp.length; i++) {
      temparray.push([dates[i], IncomesTemp[i]]);
    }

    setNewIncomes(temparray);

    setAccruedIncome(
      Number(
        currentIncomes
         .map((key) => Object.values(key)[0])
         .reduce((acc, curr) => acc + curr, 0)
         .toFixed(2)
       )
      );
  } catch (err) {
    console.log(err.response?.data);
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 11:54:04