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

禁用Strict Mode后React useEffect仍调用两次的问题求助

问题分析

你遇到的核心问题是:调用setWeekly后触发组件重渲染,进而导致useEffect再次执行——哪怕已经禁用了Strict Mode。主要可能是两个原因:

  • useEffect的依赖项配置不合理,比如依赖了会被setWeekly修改的weekly状态,或者其他会频繁变化的变量
  • 当前组件的父组件发生了不必要的重渲染,导致组件被重复渲染,间接触发useEffect
解决方法

1. 修正useEffect的依赖数组

如果这个useEffect是用来初始化加载用户数据的,依赖数组应该设为空数组([]),这样它只会在组件挂载时执行一次。示例代码:

useEffect(() => {
  const fetchUserData = async () => {
    const response = await API.graphql({ query: GET_USER_DATA });
    const total = getTotalFromItems(response);
    setWeekly(total);
  };
  fetchUserData();
}, []); // 空依赖 = 仅组件挂载时执行一次

如果必须依赖某些变量(比如当前登录用户ID),要确保这些变量是稳定的——可以用useMemo或useRef缓存,避免因变量频繁变化触发useEffect。

2. 避免无意义的状态更新

如果getTotalFromItems计算出的新值和当前weekly完全相同,没必要调用setWeekly,可以加个判断跳过:

const fetchUserData = async () => {
  const response = await API.graphql({ query: GET_USER_DATA });
  const newTotal = getTotalFromItems(response);
  if (newTotal !== weekly) { // 仅当值变化时更新状态
    setWeekly(newTotal);
  }
};

这样能避免不必要的组件重渲染,自然也不会触发useEffect重复执行。

3. 优化组件渲染逻辑

检查当前组件的父组件,看看是不是父组件的状态频繁更新导致子组件(也就是你的这个组件)重复渲染。可以给组件套一层React.memo来优化:

const ReceiptScannerComponent = React.memo(() => {
  // 你的组件逻辑代码
});

React.memo会浅比较组件的props,只有当props真的变化时才会重渲染组件。

4. 手动标记初始化完成(兜底方案)

如果前面的方法都没用,可以用useRef做一个初始化标记,强制useEffect只执行一次:

const isFirstRender = useRef(true);

useEffect(() => {
  if (isFirstRender.current) {
    const fetchUserData = async () => {
      const response = await API.graphql({ query: GET_USER_DATA });
      setWeekly(getTotalFromItems(response));
    };
    fetchUserData();
    isFirstRender.current = false;
  }
}, []);

这个方法适合排查问题时临时用,优先推荐前面的依赖项修正和状态更新优化方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 03:15:50