⛳
useStateの注意点(状態の変化のタイミング,関数コンポーネントの中の非同期関数と状態の関係)
コンポーネントの中では、再レンダリングされるまで、状態は変化しない
直感的には、setNumber 関数が3回呼び出されると number が 3 になりそうであるが、onClick を実行しても number は 1 のままである。
Counter コンポーネントが再レンダリングするときに、状態が変更されます、
import { useState } from "react";
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button
onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}
>
+3
</button>
</>
);
}
状態は非同期関数による影響は受けません
onClick を実行すると、
- setNumber 関数が実行され、React に状態を保存し、再レンダリングが予約されます。
- 非同期関数(setTimeout)を実行する。
- 再レンダリングが走り、状態が更新されて,画面に再レンダリング後の値が表示される
- setTimeout の中の関数が実行される
この時、再レンダリング前の状態を取得するので、画面に出力される alert のダイアログは再レンダリング前の状態になります。
イベント ハンドラーのコードが非同期であっても、状態変数の値がレンダリング内で変更されることはありません。
import { useState } from "react";
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button
onClick={() => {
setNumber(number + 5);
setTimeout(() => {
alert(number);
}, 3000);
}}
>
+5
</button>
</>
);
}
Discussion