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

useEffect执行两次致DB重复写入,loading状态异常排查求助

问题排查与解决方案

1. useEffect执行两次的核心原因(非SSR/SSG)

你打印window两次都存在,说明不是服务端渲染导致的——服务端环境根本不存在window对象。这大概率是React 18Strict Mode在开发环境下的刻意行为:它会重复执行useEffect、useState初始化等生命周期钩子,用来帮你检测潜在的副作用问题。

解决方法:

  • 开发环境可临时关闭Strict Mode(修改main.tsx/_app.tsx中的<StrictMode>标签),但上线前建议恢复,它能帮你提前发现隐藏bug。
  • 给useEffect添加精准依赖项,同时确保副作用是幂等的:比如用ref标记是否已执行过,或者借助trpc mutation的内置状态控制,避免重复提交。

示例代码(用ref防重复提交):

import { useRef, useEffect } from 'react';
import { trpc } from '../utils/trpc';

const MyComponent = () => {
  const hasSubmitted = useRef(false);
  const { mutate, isLoading } = trpc.myMutation.useMutation();

  useEffect(() => {
    if (!hasSubmitted.current) {
      hasSubmitted.current = true;
      mutate({ data: 'xxx' });
    }
  }, [mutate]);

  return <div>{isLoading ? '提交中...' : '已提交'}</div>;
};

2. loading状态始终为false的问题

别自己手动维护loading状态了——trpc的mutation自带isLoading状态,直接使用即可。手动维护状态很容易和trpc内部状态不同步,尤其是在Strict Mode重复执行的场景下。

如果使用trpc内置的isLoading仍有问题,排查以下几点:

  • 检查mutation调用时机:是否在组件挂载时就触发,但Strict Mode导致第一次调用被React撤销(开发环境下Strict Mode会执行两次副作用,第二次会撤销第一次的效果),导致trpc状态未更新?
  • 确认trpc客户端配置:是否开启了ssr: true但当前是纯客户端组件?若是客户端组件,要确保trpc客户端在客户端环境初始化。

3. 额外注意事项

  • 永远不要在useEffect中编写无依赖或依赖不正确的逻辑,这会导致无意义的重复执行。
  • 使用trpc mutation时,优先利用它提供的isLoading、isSuccess、isError等内置状态,避免自行维护状态引发的不一致问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 23:43:13