Day 2・state と イベント — 動くUIの心臓部
state と useState — コンポーネントが覚えておく値
画面が覚えておきたい値=stateと、それを扱うためのuseStateの読み方を学ぶ。なぜ普通の変数ではダメなのかを腹落ちさせる。
state=「画面が覚えておく値」
ボタンを押した回数、入力欄に打った文字、メニューが開いているかどうか。こうした「今の画面の状態」を表す値をstate(状態)と呼びます。ページを操作するたびに変わっていく値、と考えるとイメージしやすいです。たとえば料理中のタイマー表示。残り時間という数字が刻々と変わり、そのたびに表示も変わる。あの「変わる数字」がまさにstateです。
なぜstateという専用のしくみが必要なのか
Reactの画面は「今のstateを見て組み立てる」という作りです。値が変わったら画面も自動で描き直したい。ところが普通の変数を書き換えても、Reactは「変わった」ことに気づけません。そこで「この値はstateです」とReactに登録しておくと、値が変わったときにReactが画面を作り直してくれます。stateは、値と画面を連動させるための専用の箱なのです。
useState の読み方
stateを作るにはuseStateを使います。次の1行がReactで最も出てくる形です。左辺の角かっこは「配列を2つに分ける書き方(分割代入)」で、1つ目が今の値、2つ目がその値を更新するための関数です。命名はcountとsetCountのように「値」と「setつきの更新関数」でそろえるのが定番です。
const [count, setCount] = useState(0);
// useState(0) の 0 は「最初の値(初期値)」
// count … 今の値(最初は 0)
// setCount … count を新しい値に更新する関数
return <button onClick={() => setCount(count + 1)}>{count}</button>;useStateに渡した0は初期値です。一番最初に画面が表示されるときだけ使われ、以降はsetCountで更新された値が使われます。countをそのまま画面に{count}と埋め込めば、今の値がそのまま表示されます。
なぜ普通の変数ではダメなのか
「変わる値なら普通の変数(let count = 0)でいいのでは?」と思うかもしれません。ところがletの変数を書き換えても、Reactは画面を作り直しません。数字は裏で増えているのに、表示は0のまま固まる。値と画面がズレてしまうのです。stateにして初めて「値が変わったら描き直す」がつながります。
普通の変数:値は変わるが画面が更新されない
letを書き換えてもReactは気づかず、表示は0のまま
let count = 0;
function handleClick() {
count = count + 1; // 裏では増えるが…
}
return <button onClick={handleClick}>{count}</button>;state:値が変わると画面も更新される
setCountで更新するとReactが画面を作り直す
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1); // 値も画面も更新される
}
return <button onClick={handleClick}>{count}</button>;更新は必ずsetterで
count = count + 1 のように、stateの値を直接書き換えてはいけません。Reactが変化に気づけず画面が更新されないうえ、思わぬバグの温床になります。値を変えたいときは必ずsetCountのような更新関数(setter)を通します。
AIにはこう聞く
「このコンポーネントで覚えておくべき値(state)はどれ? useStateで書くとどうなる?」と聞くと、何をstateにすべきかと、useStateの書き方をセットで教えてくれます。既存コードを貼って「このletはstateにすべき?」と聞くのも有効です。
- stateは「画面が覚えておく、変わっていく値」
- const [値, set値] = useState(初期値) が基本形
- 1つ目が今の値、2つ目が更新用の関数
- 普通の変数を書き換えても画面は更新されない=stateにする理由
読んでも腑に落ちない所は、AIに噛み砕いてもらいましょう。
理解度チェック
答えられれば、面接で説明できる状態に一歩近づきます。
const [count, setCount] = useState(0); の setCount は何を表している?
画面に表示したい数字を let count = 0 の普通の変数にして書き換えると、どうなる?
「なぜ画面が変わる値は普通の変数ではなくstateにするのか」を、初学者に説明するつもりで書いてください。
記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。