React入門 練習問題 15:useStateとクロージャ:state更新のタイミング
次のコードを実行してボタンを1回クリックしたとき、コンソールに出力される値として正しいものはどれか。
```jsx
function Counter() {
const [count, setCount] = useState(0);
const handleClick = () => {
setCount(count + 1);
console.log(count);
};
return <button onClick={handleClick}>increment</button>;
}
```
- console.logはstateの更新前のクロージャ内の値を参照するため、0が出力される
- setCountの処理が完了してからconsole.logが実行されるため、1が出力される
- Reactが自動的にconsole.logの実行タイミングをsetCount完了後に遅延させるため、1が出力される
- countは配列として管理されているため、console.logは常に配列全体を出力する
- setCountはstate更新と同時にconsole.log内の変数countの値も書き換えるため、1が出力される
Qraftユーザーの成績:難易度 Bランク(レーティング1258)・正答率 43%(6/14回正解)
レーティングは解いた人の実力と正誤から算出する難しさ(初期値1200)。ランクはその全問題中の順位(S+が最難関、F-が最易)
正解と解説を見る
setCountを呼び出しても、その関数内のcount変数はその時点のクロージャ(=関数が作られた時点の変数の値を保持する仕組み)の値を保持し続けるため、直後のconsole.logでは更新前の値である0が出力されます。
【正解の理由】
Reactのstate更新は次のレンダリングまで反映されず、同じ関数実行内では古い値を参照し続けるため0が正解です。
【不正解の理由】
• 「setCountの処理が完了してからconsole.logが実行される」という説明は誤り。setCountは非同期的に再レンダリングを予約するだけで、その場でcount変数の値を書き換えるわけではない
• 「Reactが自動的にconsole.logの実行タイミングを遅延させる」という説明は誤り。console.logの実行タイミングはコード上の順序どおりであり遅延しない
• 「countは配列として管理されている」という説明は誤り。useStateはこの例では単一の数値を返しており配列ではない
• 「setCountはconsole.log内の変数countの値も書き換える」という説明は誤り。関数内のcountはクロージャで固定された値であり、setCountの呼び出しで書き換わることはない