umijs 报错 Invalid hook call 解决办法
今天发现某个页面由于 umi3 升级到 umi4 出现了问题,报错如下:
从报错上看可能有三种可能:
- 使用了错误的react版本
- 错误的使用了hooks
- 有多个react副本
因为 useInsertionEffect
是 react18 新引入的功能,对比项目版本,发现是符合的,排除1;
点击报错位置,进入,源码如下:
function JSXStyle(props) {
var registry = defaultRegistry ? defaultRegistry : useStyleRegistry();
// If `registry` does not exist, we do nothing here.
if (!registry) {
return null;
}
if (typeof window === "undefined") {
registry.add(props);
return null;
}
useInsertionEffect(function() {
registry.add(props);
return function() {
registry.remove(props);
};
// props.children can be string[], will be striped since id is identical
}, [
props.id,
String(props.dynamic)
]);
return null;
}
发现hooks前有判断, 那么先注释掉判断,再次尝试,依旧不行, 这种判断是恒为false的,这种并不影响react工作;
只剩下3这种可能;最终排查确实是这个问题(解决方式为将mfsu设置为false
,或者为react, react-dom 设置 externals
针对这种可能,描述下排查过程:
-
在src下报错页面添加 window.React11 = React 赋值; 在 上述
JSXStyle
添加 window.React22 = React 赋值; -
对比window.React11 === window.React22 发现返回false;
-
查找页面React引入地址与styled-jsx 引入地址, 需要将 webpack devtool设置为false, 截图如下:
页面内引入地址:
styled-jsx引入地址:
可以看到mfsu打包的模块与styled-jsx引入的模块ID不同,所以React存在两份的问题;
涉及知识:
external插件的作用,mfsu插件原理,styled-jsx/babel 插件机制;(此处占位,后续补充);
转载自:https://juejin.cn/post/7360575576418369575