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

React 18中useEffect执行两次致OAuth集成重复请求的解决方案

解决方案

针对React 18开发环境下严格模式导致的OAuth回调重复请求问题,以下是几个贴合React特性的优雅处理方式:

1. 使用useRef标记已执行状态

利用useRef在组件卸载重挂载时不会重置的特性,标记是否已经处理过授权回调,避免重复触发API请求:

const IntegrationRedirect: React.FC = () => {
  const navigate = useNavigate();
  const organisationIntegrationsService = useOrganisationIntegrationsService();
  const isProcessed = useRef(false); // 标记是否已执行过请求

  useEffect(() => {
    if (!isProcessed.current) {
      isProcessed.current = true;
      handleCreateIntegration();
    }
  }, []);

  const handleCreateIntegration = async (): Promise<void> => {
    const request: ICreateIntegration = {
      authorisationCode: ''
    };

    try {
      const setupIntegrationResponse = await organisationIntegrationsService.createIntegration(request);

      if (setupIntegrationResponse.data.errors) {
        throw 'Failed to setup integrations';
      }

      routes.organisation.integrations.navigate(navigate);
    } catch (error) {
      // 若需要允许用户重试,可在此重置标记
      // isProcessed.current = false;
    }
  };

  return null;
};

该方案仅针对开发环境的严格模式生效,无需修改用户交互流程,也不会影响生产环境的正常逻辑。

2. 让API请求实现幂等性(推荐)

从服务端层面彻底解决问题,将创建集成的POST请求设计为幂等:

  • 以授权码作为唯一标识,服务端接收到请求时先检查该授权码是否已被使用
  • 若已使用,直接返回成功响应而非错误
  • 若未使用,正常执行集成创建流程

这样即使开发环境触发两次请求,第二次也不会返回错误,用户不会看到异常提示,同时生产环境也能规避网络重试等场景下的重复创建问题。

3. 利用路由状态控制执行逻辑

在第三方重定向回应用时,通过路由状态传递未处理标记,处理完成后更新状态,避免重复执行:

const IntegrationRedirect: React.FC = () => {
  const navigate = useNavigate();
  const location = useLocation();
  const organisationIntegrationsService = useOrganisationIntegrationsService();

  useEffect(() => {
    // 检查路由状态是否标记为未处理
    if (location.state?.processed !== true) {
      handleCreateIntegration();
    }
  }, [location.state]);

  const handleCreateIntegration = async (): Promise<void> => {
    const request: ICreateIntegration = {
      authorisationCode: location.state?.authorisationCode || ''
    };

    try {
      const setupIntegrationResponse = await organisationIntegrationsService.createIntegration(request);

      if (setupIntegrationResponse.data.errors) {
        throw 'Failed to setup integrations';
      }

      // 跳转时标记状态为已处理,组件重挂载后不会重复执行
      routes.organisation.integrations.navigate(navigate, { state: { processed: true } });
    } catch (error) {
      // 处理错误
    }
  };

  return null;
};

通过路由状态持久化处理标记,即使组件被重挂载,也能根据状态判断是否需要执行请求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 09:15:32