为什么不能在循环或嵌套函数中调用React Hooks? [英] Why can't React Hooks be called inside loops or nested function?

查看:193
本文介绍了为什么不能在循环或嵌套函数中调用React Hooks?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

I understood that the order of execution was important so React can know which state corresponds to which useState call. Given that, it's obvious that a hook cannot be called inside a condition.

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

But I don't see what is the problem if we call useState inside a loop where the number of iterations doen't change over the time. Here is an example :

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;

上面的代码是否有问题?如果在每个渲染器上都调用此函数,则在嵌套函数内调用useState会有什么问题?

Is there a problem with this code above ? And what is the problem of calling useState inside a nested function, if this function is called on every render ?

推荐答案

参考指出了实际原因,

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

By following this rule, you ensure that Hooks are called in the same order each time a component renders. That’s what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

并提供示例,该示例说明了为什么这样做很重要.

and provides the example that shows why this is important.

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

Loops, conditions and nested functions are common places where the order in which hooks are executed may be disturbed. If a developer is sure that a loop, etc. is justified and guarantees the order then there's no problem.

实际上,如果将循环提取到以下位置,则它会被视为有效的自定义钩子功能,可以在需要的地方禁用linter规则(演示):

In fact, a loop would be considered valid custom hook if it was extracted to a function, a linter rule can be disabled where needed (a demo):

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

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

The example above won't cause problems but a loop isn't necessarily justified; it can be a single array state:

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>
  ));
}

这篇关于为什么不能在循环或嵌套函数中调用React Hooks?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆