前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >React报错之React hook 'useState' is called conditionally

React报错之React hook 'useState' is called conditionally

作者头像
chuckQu
发布2022-09-20 11:35:39
1.8K0
发布2022-09-20 11:35:39
举报
文章被收录于专栏:前端F2E

总览

当我们有条件地使用useState钩子时,或者在一个可能有返回值的条件之后,会产生"React hook 'useState' is called conditionally"错误。为了解决该错误,将所有React钩子移到任何可能油返回值的条件之上。

react-hook-usestate-called-conditionally.png

这里有个例子用来展示错误是如何发生的。

代码语言:javascript
复制
import React, {useState} from 'react';

export default function App() {
  const [count, setCount] = useState(0);

  if (count > 0) {
    return <h1>Count is greater than 0</h1>;
  }

  // ⛔️ React Hook "useState" is called conditionally.
  //React Hooks must be called in the exact same order
  // in every component render. Did you accidentally call
  // a React Hook after an early return?
  const [message, setMessage] = useState('');

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

上述代码片段的问题在于,我们使用的第二个useState钩子,位于可能有返回值的条件之后。

顶层调用

为了解决该问题,我们必须在最顶层调用React钩子[3]。

代码语言:javascript
复制
import React, {useState} from 'react';

export default function App() {
  const [count, setCount] = useState(0);

  // 👇️ move hooks above condition that might return
  const [message, setMessage] = useState('');

  // 👇️ any conditions that might return must be below all hooks
  if (count > 0) {
    return <h1>Count is greater than 0</h1>;
  }

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

我们把第二个useState钩子移到了可能返回值的条件之上。

这样就解决了这个错误,因为我们必须确保每次组件渲染时,React钩子都以相同的顺序被调用。

这意味着我们不允许在循环、条件或嵌套函数内使用钩子。

我们绝不应该有条件地调用钩子。

代码语言:javascript
复制
import React, {useState} from 'react';

export default function App() {
  const [count, setCount] = useState(0);

  if (count === 0) {
    // ⛔️ React Hook "useState" is called conditionally.
    // React Hooks must be called in the exact same order in every component render.
    const [message, setMessage] = useState('');
  }

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

上面的代码片段导致了错误,因为我们有条件地调用第二个useState钩子。

这是不允许的,因为钩子的数量和钩子调用的顺序,在我们的函数组件的重新渲染中必须是相同的。

为了解决这个错误,我们必须把useState的调用移到顶层,而不是有条件地调用这个钩子。

就像文档中所说的:

  • 只在最顶层使用 Hook
  • 不要在循环,条件或嵌套函数中调用 Hook
  • 确保总是在你的 React 函数的最顶层以及任何 return 之前使用 Hook
  • 在 React 的函数组件中调用 Hook
  • 在自定义 Hook 中调用其他 Hook

参考资料

[1]

https://bobbyhadz.com/blog/react-hook-usestate-called-conditionally: https://bobbyhadz.com/blog/react-hook-usestate-called-conditionally

[2]

Borislav Hadzhiev: https://bobbyhadz.com/about

[3]

最顶层调用React钩子: https://zh-hans.reactjs.org/docs/hooks-rules.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端F2E 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总览
  • 顶层调用
    • 参考资料
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档