Hook需要遵守使用的硬性规则

212 阅读2分钟
  • 不要在循环,条件或嵌套函数中调用 Hook
  • 确保在 React函数最顶层return之前 调用他们
  • 只在最顶层使用 Hook
  • 不能在event事件中和普通的JavaScript函数中调用 Hook
确保 Hook 在每一次渲染中都按照同样的顺序被调用。
这让 React 能够在多次的 `useState` 和 `useEffect` 调用之间保持 hook 状态的正确 
为了确保 Hook 的使用规则:`npm install eslint-plugin-react-hooks --save-dev` 的插件来执行Hook规则
// 你的 ESLint 配置
{
  "plugins": [
    // ...
    "react-hooks"
  ],
  "rules": {
    // ...
    "react-hooks/rules-of-hooks": "error", // 检查 Hook 的规则
    "react-hooks/exhaustive-deps": "warn" // 检查 effect 的依赖
  }
}
  • hook 应该要按顺序执行,不能因为某个条件而打乱执行顺序
  • 只要 Hook 的调用顺序多次渲染之间保持一致,React 就能正确地将内部 state 和对应的 Hook 进行关联
// 首次渲染
useState('first')                 // 1. 使用 'first' 初始化变量名的 state
useEffect(firstUpdate)            // 2. 添加 effect 以保存 update 操作
useState('second')                // 3. 使用 'second' 初始化变量名的 state
useEffect(secondUpdate)           // 4. 添加 effect 以更新 update 操作

// 二次渲染
useState('first')                 // 1. 读取变量名为 first 的 state(参数被忽略)
useEffect(firstUpdate)            // 2. 替换保存 effect
useState('second')                // 3. 读取变量名为 second 的 state(参数被忽略)
useEffect(secondUpdate)           // 4. 替换更新 effect
  • 第一次渲染中 first !== '' 这个条件值为 true,所以我们会执行这个Hook。但是下一次渲染时我们可能清空了 first,表达式值变为 false。此时的渲染会跳过该 Hook,Hook 的调用顺序发生了改变
// 在条件语句中使用 Hook 违反规则
if (first !== '') {
    useEffect(function firstUpdate() {
       …… …… …… ^^
    });
}
  • 从这里开始,后面的 Hook 调用都被提前执行,导致 bug 的产生
useState('first')              // 1. 读取变量名为 first 的 state(参数被忽略)
// useEffect(firstUpdate)      // ???? 此 Hook 被忽略!
useState('second')             // ???? 2 (之前为 3)。读取变量名为 second 的 state 失败
useEffect(secondUpdate)        // ???? 3 (之前为 4)。替换更新 effect 失败
  • 所以需要在我们组件的最顶层调用。如果我们想要有条件地执行一个 effect,可以将判断放到Hook的内部
useEffect(function firstUpdate() {
  // ????将条件判断放置在 effect 中
  if (name !== '') {
    …… …… …… ^^
  }
});

参考文献 :blog.csdn.net/zhongzk69/a…

参考文献:blog.csdn.net/gtLBTNq9mr3…


结语

前端react QQ群:788023830 ---- React/Redux - 地下老英雄

前端交流 QQ群:249620372 ---- FRONT-END-JS前端

(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习