なぜstateが必要か

画面が変わるとはどういうことか

ここまで作ってきたプロフィールサイトは、一度描いたら変わらない画面でした。ここからは「押したら数字が増える」「押したら色が変わる」ような、動く画面を作っていきます。

そのために最初に知っておきたいのは、普通の変数を書きかえても画面は変わらないという React のルールです。

動かない例を先に見る

いいねの数を表示して、ボタンを押したら 1 増やすつもりのコードです。

export default function App() { let likes = 0; function handleClick() { likes = likes + 1; console.log(likes); } return ( <div> <p>いいね {likes}</p> <button onClick={handleClick}>いいね</button> </div> ); }

これを実行してボタンを押すと、コンソールには 1、2、3 と出ます。変数はちゃんと増えています。それなのに画面の「いいね 0」は 0 のままです。

なぜ変わらないのか

理由は 2 つあります。

1 つめは、React が画面を描き直すのは コンポーネント関数をもう一度呼んだとき だけだからです。likes を書きかえても、React には「画面を作り直して」という合図が届きません。だから前に描いた <p>いいね 0</p> がそのまま残ります。

2 つめは、仮に何かのきっかけで App がもう一度呼ばれたとしても、let likes = 0; の行を最初から実行し直すので、増やした値は消えて 0 に戻ってしまうことです。

つまり普通の変数は「画面に知らせる力」も「次の呼び出しまで値を覚えておく力」も持っていません。

state が両方を引き受ける

この 2 つをまとめて解決するのが state です。state は React が預かってくれる値で、次の性質を持ちます。

  • 更新関数で変えると、React が「変わった」と気づいてコンポーネントを呼び直す
  • コンポーネントが呼び直されても、値は前の続きから始まる

書き方は useState を使います。詳しい説明は次のレッスンでしますが、形だけ先に見ておきます。

import { useState } from "react"; export default function App() { const [likes, setLikes] = useState(0); return ( <div> <p>いいね {likes}</p> <button onClick={() => setLikes(likes + 1)}>いいね</button> </div> ); }

likes = likes + 1setLikes(likes + 1) になっただけに見えますが、この違いが「画面が動くかどうか」を分けています。

つまずきどころ

コンソールに正しい数が出ていると「動いている」と思いこみがちです。動いているのは変数だけで、画面はまったく別だと切り離して考えてください。React では 画面に出したい値は必ず state にする と覚えておくと迷いません。

演習

動かないいいねボタンを、state を使って動くように直します。

ヒント

App.jsx
App.jsx
プレビュー

できているか

  • はじめは「いいね 0」と表示されている
  • ボタンを 1 回押すと「いいね 1」になる
  • そこからさらに 2 回押すと「いいね 3」になる