数字が増えない
中段 / 目安 25分
琥珀さんが首をかしげます。「いいねボタン、押しても増えないんだ。でも log を見ると中の変数は増えてる。画面だけが古い」。
これは前の4問とは毛色が違う呪いです。タイポでもなければ、参照の間違いでもありません。コードを読むかぎり「押したら1増やす」は確かに書いてあります。それでも画面は動きません。
答えは、React との契約にあります。React が画面を描き直すのは、更新関数が呼ばれたとき だけです。useState が返す配列の2つめ、setLikes のような関数がその合図です。この関数を通さずに値を変えても、React には何も伝わりません。値そのものは確かに変わっているので、console.log には新しい数が出ます。それなのに画面には前に描いたものが残り続ける。「変数は増えているのに画面だけ古い」という、いちばん気味の悪い見え方になります。
初期コードは useState を使ってはいます。使ってはいるのですが、押されたときの処理は state の値を普通の変数に写して ++ で1増やし、それをログに出しているだけです。React には何も伝わっていません。React に黙って値を変えた者は、画面に無視されます。
直し方は、その場しのぎの ++ をやめて更新関数に渡す形にすることです。処理の中身を setLikes(likes + 1) にします。画面に出したい値は必ず更新関数を通して変える、これが React の契約です。
もう一歩踏み込むと、更新関数には「今の値を受け取って次の値を返す関数」を渡す形もあります。setLikes((prev) => prev + 1) です。連続で複数回呼ぶ場面ではこちらが確実ですが、今回は1回ずつ増やすだけなので、どちらの書き方でも構いません。
配列やオブジェクトの state でも同じ話が続きます。items.push(x) は直接変更なので画面は動きません。setItems([...items, x]) のように、新しい配列を作って渡す必要があります。中身をいじるのではなく、新しい値を渡す。この癖が付くと、React の不可解な挙動の大半は消えます。
完成条件
- いいね数を state で持ち、更新関数を通して変える
- ボタンを押すたびに
classNameが like-count の要素の数が1ずつ増える ++で普通の変数を増やすだけの行を残さない
進め方
初期コードの useState の宣言はそのままで構いません。直すのは押されたときの処理の中身、1行だけです。
直したら、実際に3回押して数が3になることを目で確かめてください。ログではなく画面を見るのがこの問題の要点です。
ヒントは3段階で、①方針、②使う構文、③部分解の順に出ます。1つも開けずに通せたら、その問題は自分のものです。
供養が済むと、師範が言います。「React に黙って値を変えた者は、画面に無視される。これが契約違反の報いだ」。
ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです