R初めてのReact

Day 2state と イベント — 動く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つきの更新関数」でそろえるのが定番です。

TSX
const [count, setCount] = useState(0);
// useState(0) の 0 は「最初の値(初期値)」
// count      … 今の値(最初は 0)
// setCount   … count を新しい値に更新する関数
return <button onClick={() => setCount(count + 1)}>{count}</button>;
useStateの基本形。countが今の値、setCountが更新用の関数

useStateに渡した0は初期値です。一番最初に画面が表示されるときだけ使われ、以降はsetCountで更新された値が使われます。countをそのまま画面に{count}と埋め込めば、今の値がそのまま表示されます。

なぜ普通の変数ではダメなのか

「変わる値なら普通の変数(let count = 0)でいいのでは?」と思うかもしれません。ところがletの変数を書き換えても、Reactは画面を作り直しません。数字は裏で増えているのに、表示は0のまま固まる。値と画面がズレてしまうのです。stateにして初めて「値が変わったら描き直す」がつながります。

普通の変数:値は変わるが画面が更新されない

letを書き換えてもReactは気づかず、表示は0のまま

TSX
let count = 0;
function handleClick() {
  count = count + 1; // 裏では増えるが…
}
return <button onClick={handleClick}>{count}</button>;

state:値が変わると画面も更新される

setCountで更新するとReactが画面を作り直す

TSX
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に噛み砕いてもらいましょう。

理解度チェック

答えられれば、面接で説明できる状態に一歩近づきます。

Q1

const [count, setCount] = useState(0); の setCount は何を表している?

Q2

画面に表示したい数字を let count = 0 の普通の変数にして書き換えると、どうなる?

Q3

「なぜ画面が変わる値は普通の変数ではなくstateにするのか」を、初学者に説明するつもりで書いてください。

記述式です。まず自分の言葉で答えを考えてから、模範解答を開いて自己採点してください。