使い分け

どちらを使うか

useReducer を覚えると、何でも reducer にしたくなります。ですが検索欄の文字まで reducer にすると、書く量が増えるだけで読みやすくはなりません。使い分けの目安を持っておきます。

useState のままでよいもの

次のどれかに当てはまるなら useState です。

  • 値が1つで、更新が「新しい値に置き換える」だけ
  • 更新する場所が1か所しかない
  • 前の値を見なくても次の値が決まる

fleama で言えば、検索欄の文字、ダークモードの入り切り、モーダルの開閉です。setKeyword(e.target.value) の1行で終わる話に、action の型を足す理由はありません。

useReducer に寄せるもの

次のどれかに当てはまったら reducer を考えます。

  • 1つの操作で、複数の値が一緒に変わる
  • 次の値が、前の値の中身に依っている
  • 同じ状態を、いくつもの場所から違うやり方で更新する
  • 更新の決まりごとに、条件分岐が混じっている

カートがまさにこれです。「入れる」は、既に入っていれば数量を増やし、無ければ行を足す。前の中身を見ないと次が決まりません。更新の規則が育っていく状態は reducer 向きと覚えてください。

判断の一言

useState と useReducer のどちらが正しいか、という問いにはあまり意味がありません。どちらでも動きます。効くのは次の一言です。

この状態の更新の決まりごとを、他の人に説明する必要があるか

説明が要るなら、それは reducer に書き出せる決まりごとです。説明が要らないなら useState のままで十分です。

混ぜてよい

1つの部品の中で両方を使って構いません。カートは reducer、検索欄は useState、という形が普通です。全部を1つの巨大な reducer にまとめると、関係の無い値まで同じ action で触ることになり、かえって読みにくくなります。

演習

カートだけを reducer に移し、検索欄は useState のまま残します。

ヒント

App.tsx
App.tsx
プレビュー

できているか

  • スニーカーを入れると合計が 4800 円になる
  • 革靴 で絞り込むと 1 件になる
  • 絞り込んだ革靴も入れられて合計が 14600 円になる
  • 削除でスニーカーの行だけが消える