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

尝试展示列表添加的名称,但useEffect执行两次(Strict Mode已关)求协助

React useEffect 执行两次问题排查(已关闭 Strict Mode)

可能的触发原因

  • 组件重复挂载:父组件状态变更、路由切换、key值不稳定等情况,会导致组件被卸载后重新挂载,进而触发空依赖的useEffect执行两次。
  • React 18+ 开发环境特性:即使关闭Strict Mode,Vite/CRA的热更新机制或React DevTools的部分设置,可能在开发阶段触发额外的渲染/挂载(生产环境会自动消失)。
  • 状态初始化逻辑的连锁触发:原代码中第一个useEffect通过setInputArr修改状态,会触发组件重渲染,若此时有其他逻辑(比如父组件的重渲染)叠加,可能被误认为是useEffect执行两次。

排查步骤

  1. 验证组件挂载状态:在组件中添加挂载/卸载日志,确认是否存在重复挂载:
useEffect(() => {
  console.log("组件已挂载");
  return () => console.log("组件已卸载");
}, []);

如果日志中出现「卸载→重新挂载」,说明组件被重复创建,需要检查父组件的渲染逻辑(比如是否在循环中渲染组件、key值是否固定)。

  1. 检查开发环境配置:确认是否开启了React DevTools的「Highlight Updates」或其他调试功能,部分调试工具会强制触发重渲染;同时检查项目的热更新配置,是否存在代码修改外的自动刷新。

代码优化方案

原代码的两个useEffect存在逻辑冗余,且初始状态设置依赖useEffect容易触发不必要的重渲染,建议优化如下:

  1. 直接在useState中初始化状态:避免用useEffect读取localStorage,减少一次初始渲染:
const [inputArr, setInputArr] = useState(() => {
  try {
    const itemsArr = window.localStorage.getItem("inputArr");
    return itemsArr ? JSON.parse(itemsArr) : [];
  } catch (error) {
    console.error("解析localStorage中inputArr失败:", error);
    return [];
  }
});
  1. 保留单个useEffect负责持久化:仅在inputArr变更时写入localStorage,避免循环触发:
useEffect(() => {
  if (inputArr.length > 0) {
    window.localStorage.setItem("inputArr", JSON.stringify(inputArr));
  }
}, [inputArr]);

额外注意事项

  • 若生产环境中也出现该问题,需排查是否存在全局状态(如Redux、Context)的频繁更新导致组件重复渲染。
  • 确保inputArr的修改操作没有触发意外的状态重置,比如在其他逻辑中误调用setInputArr覆盖原有值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 00:45:06