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

React状态更新疑问:DevTools显示更新但console.log无预期结果

React状态更新后console.log无最新值的原因及代码优化建议

为什么console.log看不到更新后的values?

  • React的setState(包括useState的更新函数)是异步批量更新的,调用setValues后状态不会立即改变,紧接着的console.log(values)拿到的是更新前的闭包值。
  • 另外,浏览器控制台对引用类型(如对象)有“延迟显示”特性:直接打印对象时显示的是当前快照,但展开时会读取内存中的最新值,这也会导致日志和DevTools显示不一致——DevTools是实时读取当前状态的,所以能看到最新值。

你写的setValues函数式更新有没有问题?

这段代码是完全正确的:

setValues((prevValues) => ({
       ...prevValues,
       companyId: findCompany.id,
       departmentId: findDepartment.id,
}));

函数式更新是React推荐的写法,当新状态依赖于之前的状态时,用prevValues能确保拿到最新的状态快照,避免闭包陷阱,这里没有代码错误。

当前代码的核心问题:发送给后端的是旧数据

你在handleForm开头就创建了data对象,此时的values.companyId和values.departmentId还是初始的字符串值。之后fetchData里更新了状态,但sendData里用的还是一开始创建的旧data,所以后端收到的不是你期望的ID值。

修复方案

不要提前创建data,而是在拿到findCompany.id和findDepartment.id后,再构造包含最新值的请求数据:

// 修改fetchData,返回新的companyId和departmentId
const fetchData = async () => {
  if (
    typeof values.companyId === "string" &&
    typeof values.departmentId === "string"
  ) {
    const [companyRes, departmentRes] = await Promise.all([
      axiosInstance.get("/company"),
      axiosInstance.get("/department"),
    ]);

    const company = values.companyId.slice(
      0,
      values.companyId.indexOf("(")
    );
    const findCompany = companyRes.data.result.find(
      (item) => item.name === company
    );
    const findDepartment = departmentRes.data.result.find(
      (item) => item.name === values.departmentId
    );

    // 更新状态(供组件内部使用)
    setValues((prevValues) => ({
      ...prevValues,
      companyId: findCompany.id,
      departmentId: findDepartment.id,
    }));

    // 返回新ID,给sendData构造请求体用
    return {
      companyId: findCompany.id,
      departmentId: findDepartment.id
    };
  }
  return null;
};

// 修改sendData,接收最新的ID参数
const sendData = async (newIds) => {
  if (!newIds) return;
  // 构造包含最新ID的请求数据
  const data = {
    firstName: values.firstName,
    lastName: values.lastName,
    firstNameHiragana: values.firstNameHiragana,
    lastNameHiragana: values.lastNameHiragana,
    companyId: newIds.companyId,
    birthday: values.birthday,
    sex: values.sex === "somestring" ? 0 : 1,
    mail: values.email,
    telephone: values.telephone,
    enterDate: values.enterDate,
    departmentId: newIds.departmentId,
    commissioningStatusId: values.commissionStatusId === "somestring" ? 0 : 1,
    houseStatusId: values.houseStatusId,
    businessManager: values.businessManager,
  };

  try {
    const response = await axiosInstance.post("/employee", data, {
      headers: headers,
    });
    console.log(response);
  } catch (error) {
    console.log(error);
  }
};

// 按顺序调用并传递新ID
(async () => {
  const newIds = await fetchData();
  await sendData(newIds);
})();

额外调试建议

如果要查看状态更新后的结果,不要在setValues后立即console.log,可以用useEffect监听values的变化:

useEffect(() => {
  console.log("最新的values:", values);
}, [values]);

这样每次values更新时,都会打印最新值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:25:05