React:在循环和嵌套函数内调用 Hooks 的错误示例

Gle*_*mad 5 reactjs react-hooks

Hooks 的第一条规则是仅在顶层调用 Hooks,即“Don\xe2\x80\x99t 在循环、条件或嵌套函数内调用 Hooks”。该文档通过一个在条件内调用 Hooks 的示例非常清楚地解释了这一点,但不适用于其他两种情况:循环和嵌套函数。

\n\n

是否有在循环和嵌套函数内调用 Hooks 时可能出错的示例?此外,自定义钩子不就是一个嵌套函数吗?

\n\n

不幸的是,此处此处为这两个相关问题提供的答案仅给出了正确的示例。

\n

Apr*_*ion 5

可变长度循环的示例:

const {useState} = React

const WrongLoop = () => {
  const [count, setCount] = useState(1)
  for (let i = 0; i < count; i++) {
    const [x, setX] = useState(i)
  }
  const [unknownOrder, setUnknownOrder] = useState('some state')
  
  return <button onClick={() => setCount(c => c+ 1)}>{count} {unknownOrder}</button>
}

ReactDOM.render(<WrongLoop />, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)

eslint 很难检测到的嵌套函数示例(自定义钩子是一种特殊情况 - 当use...在函数名称中使用前缀时,可以通过 eslint 静态分析它在组件中的用法):

const {useState} = React

const fn = () => {
  const [x, setX] = useState() // is it OK to use hooks unconditionally here?
}

const WrongFn = () => {
  const [count, setCount] = useState(1)
  if (count === 1) {
    fn() // OK to use normal functions conditionally.. but what if there's a hook inside?
  }
  const [unknownOrder, setUnknownOrder] = useState('some state')
  
  return <button onClick={() => setCount(c => c+ 1)}>{count} {unknownOrder}</button>
}

ReactDOM.render(<WrongFn />, document.getElementById('root'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>
Run Code Online (Sandbox Code Playgroud)