React useEffect函数执行顺序异常:严格模式引发的问题分析
React严格模式下useEffect中ApiCall_B未等待ApiCall_A完成的问题分析
问题场景
我尝试用React的useEffect实现ApiCall_A执行完成后再调用ApiCall_B的逻辑,代码如下:
useEffect(() => { ApiCall_A() .then(ApiCall_B) }, []);
但实际运行中发现ApiCall_B并未等待ApiCall_A执行完成就提前触发,多次调整useEffect写法都无法解决,于是排查ApiCall_A的实现:
async function ApiCall_A() { const gid = getGrandidsession(); if (gid) { await handleOrderSignature(gid); } } async function handleOrderSignature(gid) { const order = JSON.parse(sessionStorage.getItem("ORDER_TO_BE_PLACED")); if (order) { sessionStorage.removeItem("ORDER_TO_BE_PLACED"); order.grandIdSession = gid; const res = await placeOrder(order, order.placedByOrgId); // 耗时API调用 } }
问题根源
经过排查,问题出在React严格模式上:
- React严格模式(仅开发环境)会让组件挂载两次
- 第一次挂载时,
sessionStorage.removeItem("ORDER_TO_BE_PLACED")已删除对应数据 - 第二次挂载时,
sessionStorage.getItem("ORDER_TO_BE_PLACED")返回null,导致handleOrderSignature中的if (order)分支不执行,ApiCall_A直接提前结束,进而触发了then回调里的ApiCall_B
解决方案建议
针对该问题,可从以下方向处理:
- 避免依赖sessionStorage的一次性数据被重复消费:改用组件状态、Context等方式存储临时订单数据,或者读取数据时增加已处理标识判断,防止严格模式下的重复执行
- 给异步操作加锁:添加执行标识,阻止严格模式下的第二次挂载重复触发逻辑,示例代码:
let isProcessing = false; async function ApiCall_A() { if (isProcessing) return; isProcessing = true; try { const gid = getGrandidsession(); if (gid) { await handleOrderSignature(gid); } } finally { isProcessing = false; } }
- 开发环境临时关闭严格模式:若仅为验证逻辑,可暂时移除根组件的
<React.StrictMode>包裹,但不建议长期这么做——严格模式能帮助提前发现潜在代码问题
内容的提问来源于stack exchange,提问作者Ideefix Lindé
相关产品推荐
相关产品推荐

