为什么 useState 不会触发重新渲染? [英] Why is useState not triggering re-render?

查看:229
本文介绍了为什么 useState 不会触发重新渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经初始化了一个数组状态,当我更新它时,我的组件不会重新渲染.这是一个最小的概念验证:

function App() {const [numbers, setNumbers] = React.useState([0, 1, 2, 3]);console.log(渲染中...");返回 (

{numbers.map(number => (<p>{数字}</p>))}<输入类型=文本"值={数字[0].toString()}onChange={newText =>{让旧 = 数字;旧 [0] = 1;setNumbers(旧);}}/>

);}

基于这段代码,输入似乎应该包含数字 0 开始,并且任何时候它改变,状态也应该改变.进入02"后在输入中,App 组件不会重新渲染.但是,如果我在 5 秒后执行的 onChange 函数中添加 setTimeout,则表明数字确实已更新.

对组件不更新的原因有什么想法吗?

这是一个带有概念证明的 CodeSandbox.

解决方案

您正在调用 setNumbers 并将它已有的数组传递给它.你已经改变了它的一个值,但它仍然是同一个数组,我怀疑 React 没有看到任何重新渲染的理由,因为状态没有改变;新数组是旧数组.

避免这种情况的一种简单方法是将数组扩展到一个新数组中:

setNumbers([...old])

I've initialized a state that is an array, and when I update it my component does not re-render. Here is a minimal proof-of-concept:

function App() {
  const [numbers, setNumbers] = React.useState([0, 1, 2, 3]);
  console.log("rendering...");
  return (
    <div className="App">
      {numbers.map(number => (
        <p>{number}</p>
      ))}
      <input
        type="text"
        value={numbers[0].toString()}
        onChange={newText => {
          let old = numbers;
          old[0] = 1;
          setNumbers(old);
        }}
      />
    </div>
  );
}

Based on this code, it seems that the input should contain the number 0 to start, and any time it is changed, the state should change too. After entering "02" in the input, the App component does not re-render. However, if I add a setTimeout in the onChange function which executes after 5 seconds, it shows that numbers has indeed been updated.

Any thoughts on why the component doesn't update?

Here is a CodeSandbox with the proof of concept.

解决方案

You're calling setNumbers and passing it the array it already has. You've changed one of its values but it's still the same array, and I suspect React doesn't see any reason to re-render because state hasn't changed; the new array is the old array.

One easy way to avoid this is by spreading the array into a new array:

setNumbers([...old])

这篇关于为什么 useState 不会触发重新渲染?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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