React17 升级到 18,我的 useEffect 就炸了?

57 阅读1分钟

useEffect

报错

报错

报错Fg函数

报错Fg函数

报错Cg函数

报错Cg函数

寻找Fg对应React源码

Fg对应React源码 (组件卸载或依赖变更时执行useEffect的destory函数)

寻找Cg对应React源码

Cg对应React源码(调用destory)

分析错误原因,useEffect 返回了一个即不是underfined也不是函数的值,排查相关页面及组件代码

断点后结果 进一步分析,报错原因是useEffect返回了一个Promise

解决方案

使用正则表达式

// 检查useEffect中是async函数
/useEffect\s*\(\s*async/
  
// 检查useEffect中直接return是值或者Promise
/useEffect\s*\(\s*\(\s*\)\s*=>\s*\w/

找出所有useEffect中使用了async的地方(53处),如需要async的地方修改如下,不需要的地方直接删除async

// 修改前
useEffect(async () => {
  // ...
}, [])

// 修改后
useEffect(()=> {
  const handler = async () => {
    // ...
  }
  handler()
}, [])

以上是临时解决方案,在 useEffect 中使用异步可能还会产生其他副作用,需要考虑怎么清除。

为啥升级前不会报错

react18跟react17在调用useEffect的destroy时的实现不一样。React17判断destroy是函数的情况下才会去调用。 React17 (判断destroy是函数的情况下才会去调用)