症状
添加了文章图片点击放大功能后,界面交互正常,但无意间发现控制台出现了报错:
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.
提示 Invalid hook call
错误,并且给了相关链接: https://react.dev/link/invalid-hook-call
原因
我们访问 链接 可以看到一个关于 Rules of Hooks 的文档,里面详细说明了控制台报错的 3
种情况:
1. Breaking Rules of Hooks
这些情况违反了
React Hooks
的使用规范,需要检查代码中 Hooks
的使用情况。
2. Mismatching Versions of React and React DOM
使用的
react-dom
或者 react-native
版本太低。
3. Duplicate React
react
和 react-dom
导入的模块不一致,可在 index.js
中导入 react
查看:
// Add this in node_modules/react-dom/index.js
window.React1 = require('react');
// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2);
经过排查发现,文章详情页里面引用了 2
个 React
组件,一一屏蔽运行后原来是我新增的 ImageViewer
组件有问题。
将文档和代码提交给 AI
分析后, 发现 handleClick
中更新了多个状态,违反了:
Do not call Hooks in event handlers
规范。
// 问题代码
const handleClick = (e: MouseEvent) => {
e.preventDefault();
e.stopPropagation();
setIsLoading(true);
setCurrentImage(img.src);
setCurrentAlt(img.alt || "");
setIsOpen(true);
};
解决
询问 AI
解决方案:
将
AI
优化的代码调整到组件中:
const dispatchRef = useRef(dispatch);
useEffect(() => {
dispatchRef.current = dispatch;
});
// 其他代码...
const handleClick = (e: MouseEvent) => {
e.preventDefault();
e.stopPropagation();
dispatchRef.current({
type: "OPEN_IMAGE",
src: img.src,
alt: img.alt || "",
});
};
🎉🎉🎉 刷新页面,这个问题解决了!😄
此外,文档中提到可以用 eslint-plugin-react-hooks
来 catch
住 Breaking Rules of Hooks 规范。我们项目用的是 biome
,biome
对于 eslint-plugin-react-hooks
的相关配置configure:
{
"linter": {
"rules": {
"correctness": {
"useExhaustiveDependencies": "error",
"useHookAtTopLevel": "error"
}
}
}
}
但是经过测试,发现对 Do not call Hooks in event handlers 规范无效,对其他规范是有效的:
总结
- 注意
React Hooks
的使用规范 - 利用
AI
辅助分析问题