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

React StrictMode下Redux拉取数据时action重复触发问题

问题成因

该问题是React 18+版本<React.StrictMode>开发环境的预期行为,和Redux本身无关:

  • 开发模式下StrictMode会主动执行两次组件挂载-卸载流程,用来提前检测代码中不规范的副作用逻辑,比如缺失清理逻辑的useEffect、不安全的生命周期调用等。生产环境下StrictMode不会触发该双重执行逻辑,因此移除StrictMode包裹后功能暂时恢复正常,但这属于规避问题而非修复。
  • 你当前写在useEffect中的数据请求逻辑没有做请求中止、竞态处理、重复触发拦截,组件双重挂载时effect会执行两次,对应重复发起请求、重复dispatch action,最终出现请求重复发、数据重复追加到store的问题。
正确修复方案

不要通过移除StrictMode解决问题,只需要补全副作用的规范处理逻辑即可:

  • 给异步请求增加AbortController中止控制,在useEffect的清理函数中中止未完成的上一次请求,避免组件重挂载时的无效请求和过期dispatch
  • 增加加载状态锁,请求发起前判断当前是否已经处于加载中,是则直接拦截不重复触发
  • 针对加载更多的追加场景,增加游标参数和数据去重逻辑,避免硬编码拉取参数导致的重复数据问题

修复后的App组件参考代码:

function App() {
  const dispatch = useDispatch();
  const data = useSelector(questionsData);
  // 从store中取出loading状态做请求锁
  const loading = useSelector(state => state.questionsStore.loading);

  useEffect(() => {
    const abortController = new AbortController();
    const fetchQuestions = async () => {
      // 加载中直接拦截,不重复发请求
      if (loading) return;
      dispatch(fetchQuestionsBegin());
      try {
        // 把abort信号传给请求实例,支持主动中止
        const { data } = await mainUrl(`/questions?last=5`, {
          signal: abortController.signal
        });
        // 确认请求未被中止再dispatch结果
        if (!abortController.signal.aborted) {
          dispatch(fetchQuestionsSuccess(data));
        }
      } catch (err) {
        // 过滤主动中止的请求错误,只处理真实请求失败
        if (!abortController.signal.aborted) {
          dispatch(fetchQuestionsFailure(err?.message || '请求失败'));
        }
      }
    };
    fetchQuestions();

    // effect清理函数:组件重执行/卸载前中止上一次未完成的请求
    return () => abortController.abort();
  }, [dispatch, loading]);

  return (
    <>
      <div>TEST</div>
    </>
  );
}

如果项目中异步请求逻辑较多,推荐直接使用Redux Toolkit官方的createAsyncThunk工具编写异步逻辑,它内置了竞态处理、请求中止、状态自动管理的能力,不需要手动在组件中处理重复触发问题,代码稳定性更高。

注意:StrictMode的双重执行是React提供的代码隐患检测机制,修复副作用清理逻辑后,不管是开发环境的双重挂载、还是生产环境中组件意外重挂载、网络请求延迟导致的竞态问题,都不会再出现action重复触发、数据重复追加的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:12:42