只能在函数组件的顶级作用域使用

只能在函数组件的顶级作用域使用

Content #

所谓顶层作用域,就是 Hooks 不能在循环、条件判断或者嵌套函数内执行,而必须是在顶层。同时 Hooks 在组件的多次渲染之间,必须按顺序被执行。因为在 React 组件内部,其实是维护了一个对应组件的固定 Hooks 执行列表的,以便在多次渲染之间保持 Hooks 的状态,并做对比。

比如说下面的代码是可行的,因为 Hooks 一定会被执行到:

function MyComp() {
  const [count, setCount] = useState(0);
  // ...
  return <div>{count}</div>;
}

而下面的代码是错误的,因为在某些条件下 Hooks 是不会被执行到的:

function MyComp() {
  const [count, setCount] = useState(0);
  if (count > 10) {
    // 错误:不能将 Hook 用在条件判断里
    useEffect(() => {
      // ...
    }, [count])
  }
  // 这里可能提前返回组件渲染结果,后面就不能再用 Hooks 了
  if (count === 0) {
    return 'No content';
  }
  // 错误:不能将 Hook 放在可能的 return 之后
  const [loading, setLoading] = useState(false);
  //...
  return <div>{count}</div>
}

所以 Hooks 的这个规则可以总结为两点:

  1. 所有 Hook 必须要被执行到。
  2. 必须按顺序执行。

Viewpoints #

From #

03|内置 Hooks(1):如何保存组件状态和使用生命周期?