なぜ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 + 1 が setLikes(likes + 1) になっただけに見えますが、この違いが「画面が動くかどうか」を分けています。
つまずきどころ
コンソールに正しい数が出ていると「動いている」と思いこみがちです。動いているのは変数だけで、画面はまったく別だと切り離して考えてください。React では 画面に出したい値は必ず state にする と覚えておくと迷いません。
演習
動かないいいねボタンを、state を使って動くように直します。