修复React中 "React Hook被有条件地调用 "的错误的方法

192 阅读2分钟

如果你是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>;
}

就是这样--你现在在每次渲染时都运行钩子(按要求),但如果你需要,你仍然可以在钩子里提前退出。