1. ホーム
  2. javascript

[解決済み] useStateが再レンダリングのトリガーにならないのはなぜですか?

2022-04-28 10:21:16

質問

状態を配列で初期化したのですが、それを更新してもコンポーネントが再レンダリングされません。以下は、最小限の概念実証です。

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という数字が入っていて、それを変更するたびに状態も変化するはずです。input に "02" を入力した後、App コンポーネントは再レンダリングされません。しかし、onChange関数にsetTimeoutを追加し、5秒後に実行すると、確かに数字が更新されたことが示されます。

なぜコンポーネントが更新されないのか、何か思い当たることはありますか?

以下は コードサンドボックス をコンセプトの証明とする。

解決方法は?

あなたが呼んでいるのは setNumbers で、すでに持っている配列を渡しています。あなたは値のひとつを変更しましたが、それはまだ同じ配列です。Reactは状態が変化していないため、再レンダリングの理由を見出さないのでしょう。

これを避ける簡単な方法のひとつは、配列を新しい配列に分散させることです。

setNumbers([...old])