为什么 useState 不触发重新呈现?

2022-08-30 01:38:49

我已经初始化了一个数组状态,当我更新它时,我的组件不会重新呈现。下面是一个最小的概念验证:

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

基于此代码,输入似乎应包含数字 0 才能开始,并且每当更改时,状态也应该更改。在输入中输入“02”后,应用组件不会重新呈现。但是,如果我在 onChange 函数中添加一个 setTimeout,该函数在 5 秒后执行,则表明数字确实已更新。

关于组件为什么不更新的任何想法?

这是一个带有概念验证的CodeSandbox


答案 1

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

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

setNumbers([...old])

答案 2

您需要像这样复制numberslet old = [...numbers];

useState仅当值已更改时才不更新该值,因此,如果它是并且它变成了它将更新。但是它如何知道数组或对象是否已更改。它是通过引用,所以当你这样做时,你只是传递一个引用,而不是创建一个新的引用447let old = numbers