React组件挂载时触发两次认证请求的原因排查
解决Salesforce Marketing Cloud认证时useEffect触发两次请求的问题
核心原因分析
React Strict Mode 开发环境特性
开发模式下的Strict Mode会刻意重复执行useEffect、组件挂载等逻辑,目的是检测潜在的副作用问题。这是最常见的触发两次请求的原因——生产环境下该行为会自动消失,但开发时会导致认证逻辑跑两次,而SFMC的授权code通常只能使用一次,所以第二次请求必然报错。组件重复挂载
组件可能被意外重复渲染或挂载:比如路由切换时组件被卸载后重新挂载、父组件的key属性变化导致子组件重建、组件被多次嵌套在不同位置,或者条件渲染逻辑导致组件反复挂载卸载。
解决方案
1. 给认证逻辑加执行锁(最直接有效)
用useRef标记是否已经执行过认证流程,避免重复触发。因为useRef的current值不会触发组件重渲染,适合做这种状态标记:
import { useEffect, useRef } from 'react'; // ... 其他组件代码 const isInitialized = useRef(false); useEffect(() => { async function initialize() { // 已经执行过就直接返回 if (isInitialized.current) return; isInitialized.current = true; const params = await getParamsFromUrl(); if (params.code) { try { await getTokenAndSaveToSession(params.code); await fetchJourneyData(); } catch (error) { console.error('认证失败:', error); } } else { console.log('URL参数中没有授权code'); } } initialize(); }, []); async function getTokenAndSaveToSession(code: string) { try { const authService = new AuthService(); const result = await authService.getToken(code); sessionStorage.setItem('token', result.token); sessionStorage.setItem('expiration', result.expiration.toString()); } catch (error) { console.log(error); } }
2. 排查组件重复挂载问题
- 检查路由配置,确保组件没有被多次注册
- 查看父组件是否有不必要的
key变更,或者条件渲染导致组件反复卸载/挂载 - 确认组件是否被多个父组件实例引用
3. 处理Strict Mode(可选)
如果只是想在开发环境避免这个问题,可以暂时移除index.tsx中包裹应用的<React.StrictMode>标签,但不建议长期这么做——Strict Mode能帮你提前发现很多潜在的代码问题。
额外注意点
SFMC的授权code是一次性的,所以即使解决了重复请求的问题,也要确保:
- 认证流程执行一次后,及时从URL中移除
code参数(避免用户刷新页面再次触发错误) - 在
getTokenAndSaveToSession中加入逻辑,先检查sessionStorage中是否已有有效token,再决定是否发起请求
内容的提问来源于stack exchange,提问作者Student
相关产品推荐
相关产品推荐

