为什么不能在循环或嵌套函数中调用React Hook?

Oli*_*ssé 5 reactjs react-hooks

React Hooks文档不要在循环,条件或嵌套函数中调用Hooks.

我知道执行的顺序很重要,所以React可以知道哪个状态对应于哪个useState调用.鉴于此,显然无法在条件内调用钩子.

但是如果我们useState在一个迭代次数不随时间变化的循环中调用,我看不出是什么问题.这是一个例子:

const App = () => {
  const inputs = [];

  for(let i = 0; i < 10; i++) {
    inputs[i] = useState('name' + i);
  }

  return inputs.map(([value, setValue], index) => (
    <div key={index}> 
      <input value={value} onChange={e => setValue(e.target.value)} />
    </div>
  ));
}

export default App;
Run Code Online (Sandbox Code Playgroud)

上面的代码有问题吗?useState如果在每个渲染上调用此函数,那么在嵌套函数内部调用的问题是什么?

Est*_*ask 6

参考文献说明了实际原因,

通过遵循此规则,您可以确保每次组件呈现时都以相同的顺序调用Hook.这就是允许React在多个useState和useEffect调用之间正确保留Hook状态的原因.

并提供说明为什么这很重要的例子.

循环,条件和嵌套函数是常见的地方,其中执行挂钩的顺序可能会受到干扰.如果开发人员确定循环等是合理的并且保证订单那么就没有问题.

实际上,如果将循环提取到函数中,则循环将被视为有效的自定义挂钩:

// eslint-disable-next-line react-hooks/rules-of-hooks
const useInputs = n => [...Array(n)].map((_, i) => useState('name' + i));
Run Code Online (Sandbox Code Playgroud)

上面的例子不会引起问题,但循环不一定合理; 它可以是单个数组状态:

const App = () => {
  const [inputs, setInputs] = useState(Array(10).fill(''));
  const setInput = (i, v) => {
    setInputs(Object.assign([...inputs], { [i]: v }));
  };

  return inputs.map((v, i) => (
    <div key={i}> 
      <input value={v} onChange={e => setInput(i, e.target.value)} />
    </div>
  ));
}
Run Code Online (Sandbox Code Playgroud)

  • 所以这句话 **Don't call Hooks inside loops, conditions, or nested functions.** 是错误的。如果遵守顺序,我们可以在循环内调用钩子 (3认同)