サンプルコード
const Count = () => {
const [count, setCount] = useState(0);
const handleClick = () = {
setCount(count + 1);
setCount(count + 1);
setCount(count + 1);
}
return (
<>
<p> count: {count}</p>
<button onClick={handleClick}> click! </button>
</>
)
}
上記のコンポーネントにおいて、ボタンをクリックしてもcountが+1されるだけなのはなぜか。
この理由を「状態はスナップショットである」ことから説明できる。
スナップショットとは
ある時点での情報をそのまま写し取ったものみたいな意味合いで使われることが多い。
useStateで管理される状態は、ある時点での値を写し取ったものでしかない。ある時点とは、たとえば状態が変更された時(レンダリングトリガー)などがある。
Reactのレンダリング→画面描画までをおさらい
- 状態が変更される(レンダリングトリガー)
- コンポーネントが呼び出され、実行される(レンダリング)
- 仮想DOMが作成される
- 仮想DOMと実DOMの差分を検出
- 差分があれば実DOMを更新する
なぜcountは+1しかされない?
コンポーネントは、コンポーネントが呼び出された時点での状態(状態のスナップショット)をもとに、実行されるから。
countが0のとき、handleClick()は実質以下の内容になっている。
const handleClick = () = {
setCount(0 + 1);
setCount(0 + 1);
setCount(0 + 1);
}
これは、コンポーネントがレンダリングされるときの状態は0だったため、このような挙動になる。
参考