React Hook使用

173 阅读2分钟

Hook规则

Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则。并且React要求强制执行这两条规则,不然就会出现异常的bug
  • 只在最顶层使用 Hook

不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层调用他们

  • 只在 React 函数中调用 Hook

不要在普通的 JavaScript 函数中调用 Hook,这两条规则出现的原因是,我们可以在单个组件中使用多个State Hook 或 Effect Hook,React 靠的是 Hook 调用的顺序来知道哪个 state 对应哪个useState

function Form() {
  const [name1, setName1] = useState('Arzh1');
  const [name2, setName2] = useState('Arzh2');
  const [name3, setName3] = useState('Arzh3');
  // ...
}
// ------------
// 首次渲染
// ------------
useState('Arzh1')       // 1. 使用 'Arzh1' 初始化变量名为 name1 的 state
useState('Arzh2')       // 2. 使用 'Arzh2' 初始化变量名为 name2 的 state
useEffect('Arzh3')     	// 3. 使用 'Arzh3' 初始化变量名为 name3 的 state

// -------------
// 二次渲染
// -------------
useState('Arzh1')        // 1. 读取变量名为 name1 的 state(参数被忽略)
useState('Arzh2')        // 2. 读取变量名为 name2 的 state(参数被忽略)
useEffect('Arzh3')       // 3. 读取变量名为 name3 的 state(参数被忽略)

如果我们违反React的规则,使用条件渲染

if (name !== '') {
    const [name2, setName2] = useState('Arzh2');
}

假设第一次(name !== '')为true的时候,执行此Hook,第二次渲染(name !== '')为false时,不执行此Hook,那么Hook的调用顺序就会发生变化,产生bug

useState('Arzh1')        // 1. 读取变量名为 name1 的 state
//useState('Arzh2')        // 2. Hook被忽略
useEffect('Arzh3')       // 3. 读取变量名为 name2(之前为name3) 的 state

React 不知道第二个 useState 的 Hook 应该返回什么。React 会以为在该组件中第二个 Hook 的调用像上次的渲染一样,对应的是 arzh2 的 useState,但并非如此。所以这就是为什么React强制要求Hook使用必须遵循这两个规则,同时我们可以使用 eslint-plugin-React-Hooks来强制约束