如果你是React钩子的新手,你可能会发现自己遇到了这个有点神秘的错误。让我们深入了解它是什么以及如何修复它。
它是什么意思?
只在顶层调用钩子
不要在循环、条件或嵌套函数中调用Hooks。相反,总是在你的React函数的顶层使用Hooks,在任何早期返回之前。通过遵循这一规则,你可以确保每次组件渲染时,Hooks被以相同的顺序调用。这就是让React在多次调用useState和useEffect之间正确保存Hooks的状态。
这里的TL;DR是,在你从一个组件中提前return ,在一个循环中,或在一个条件中,你不能使用任何钩子。
为什么会发生这种情况?
你的组件很有可能看起来像这样。
例1
function MyComponent() {
if (someCondition) {
return <p>Some information</p>;
}
useEffect(() => {
// Do something
}, []);
return <p>Some other information</p>;
}
或者像这样。
例2
function MyComponent() {
if (someCondition) {
useEffect(() => {
// Do something
}, []);
}
return <p>Some other information</p>;
}
或者甚至像这样。
例三
function MyComponent() {
myArray.forEach((el) => {
useEffect(() => {
// Do something
}, []);
});
return <p>Some other information</p>;
}
这些例子都打破了钩子的第一条规则!
- 例子1在调用
useEffect钩子之前提前返回。 - 例2在一个条件中调用
useEffect钩子 - 例子3在一个循环中调用
useEffect钩子
如何修复这个错误
这个解决方案对于特定的用例来说有点特立独行,但一般来说,我经常看到上面的例子1和2。通常情况下,你要确保一个效果在某些条件下不会运行。
有条件地运行效果
由于钩子必须在每个组件渲染时运行,所以从技术上讲,你不能有条件地运行useEffect 钩子。但是,你可以在 useEffect 钩子里面有条件地提前返回。
让我们看看这将是什么样子。
function MyComponent() {
useEffect(() => {
if (someCondition) {
return;
}
// Do something only when `someCondition` is falsey
}, []);
return <p>Some other information</p>;
}
就是这样--你现在在每次渲染时都运行钩子(按要求),但如果你需要,你仍然可以在钩子里提前退出。