React useEffect致/api/checkCookie接口重复调用4次问题排查
问题分析与解决方案
核心问题
API请求被触发4次,主要由以下原因导致:
自定义Hook错误标记为async
React Hook必须是同步函数,给useCheckCookieToken加上async关键字会破坏Hook执行规则,引发组件渲染逻辑异常,可能导致副作用重复执行。React Strict Mode的开发环境行为
开发模式下,React Strict Mode会主动触发两次组件挂载/卸载流程(执行useEffect后立即调用清理函数,再重新执行useEffect),用于检测副作用泄漏。如果TableComp被渲染两次,就会出现4次API请求。状态初始值未明确设置
useState()初始值为undefined,导致组件首次渲染时session !== null为true,直接渲染子组件;fetch完成后setSession又触发一次重渲染,增加了不必要的渲染周期。
修复步骤
1. 移除自定义Hook的async关键字
Hook本身不能是异步函数,修改后的代码如下:
function useCheckCookieToken() { const [session, setSession] = useState(null); // 明确初始值为null useEffect(() => { const controller = new AbortController(); // 添加请求取消控制器 const signal = controller.signal; async function sessionPost() { try { const res = await fetch(`/api/checkCookie`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, signal // 绑定取消信号 }); if (res.ok) { const result = await res.json(); setSession(result); } else { setSession(null); // 请求失败时重置状态 } } catch (err) { if (err.name !== 'AbortError') { console.error('请求失败:', err); setSession(null); } } } sessionPost(); return () => { controller.abort(); // 组件卸载时取消请求 console.log('unmount'); }; }, []); return session; } module.exports = { useCheckCookieToken };
2. 处理Strict Mode的重复请求(可选)
开发环境下Strict Mode的两次执行是正常现象,生产环境会自动消失。如果想在开发环境避免重复请求,可以添加请求锁:
function useCheckCookieToken() { const [session, setSession] = useState(null); const isRequested = useRef(false); // 标记是否已发起请求 useEffect(() => { if (isRequested.current) return; isRequested.current = true; const controller = new AbortController(); const signal = controller.signal; async function sessionPost() { // 原有请求逻辑 } sessionPost(); return () => { controller.abort(); isRequested.current = false; // 卸载时重置标记 console.log('unmount'); }; }, []); return session; }
3. 检查组件挂载次数
确认TableComp是否被父组件多次渲染,比如路由配置错误、条件渲染逻辑重复等。可以在组件中添加日志排查:
function TableComp() { const session = useCheckCookieToken(); console.log('TableComp渲染'); // 查看渲染次数 return ( session !== null ? <> <Menu /> <AddService /> <DataTable /> </> : <Navigate to="/" /> ); }
验证
修复后,开发环境下Strict Mode会触发2次请求(生产环境1次)。如果仍出现4次请求,需检查是否有多个组件实例调用了useCheckCookieToken,或父组件存在不必要的重渲染导致TableComp多次挂载。
内容的提问来源于stack exchange,提问作者XAZG Неизвестный
相关产品推荐
相关产品推荐

