乐趣区

关于react.js:React报错之React-hook-useState-is-called-conditionally

注释从这开始~

总览

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

这里有个例子用来展现谬误是如何产生的。

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 钩子。

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 钩子都以雷同的程序被调用。

这意味着咱们不容许在循环、条件或嵌套函数内应用钩子。

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

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
退出移动版