React 18严格模式组件双渲染axios AbortController报错求解
问题根因
React 18 严格模式在开发环境下会自动执行一次「组件挂载→卸载→重新挂载」的流程,目的是提前暴露副作用逻辑没有正确清理的隐患。你的代码里没有区分「AbortController主动取消请求抛出的错误」和「真实业务/鉴权错误」:第一次挂载触发的接口请求会被卸载阶段执行的controller.abort()主动取消,抛出的取消错误被catch块捕获后,直接触发了跳转到登录页的逻辑,就会出现已登录用户被重定向、控制台持续报错的问题。
修复方法
axios 对主动取消的请求做了专属错误标记,这类错误的code字段固定为ERR_CANCELED,只需要在catch块中过滤掉这类错误,不执行跳转逻辑即可:
useEffect(() => { const controller = new AbortController(); const getGoals = async () => { try { const response = await goalPrivate.get("/goals", { signal: controller.signal }) setGoals(response?.data); } catch (error) { // 主动取消的请求直接跳过,不做错误处理 if (error.code === "ERR_CANCELED") return; console.log(error.message); // 仅真实请求异常(如refreshToken过期)才触发登录跳转 navigate("/login", { state: { from: location }, replace: true }); } } getGoals(); // 清理函数 return () => { controller.abort(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [])
注意事项
- 严格模式下的双挂载、双执行effect逻辑仅在开发环境生效,生产环境构建后不会触发该行为,不会影响线上用户使用
- 不需要为了规避这个问题关闭严格模式,该机制是React官方提供的代码健壮性校验手段,过滤主动取消的请求错误才是符合设计预期的正确写法
- 原代码中的
isMounted标记可以移除:请求被主动取消后会直接抛出错误,不会走到后续setGoals的状态更新逻辑,不会触发「已卸载组件更新状态」的警告。
内容的提问来源于stack exchange,提问作者Ifeanyi Chima
相关产品推荐
相关产品推荐

