つくる - カート完成
第6章のまとめとして作る
新しいことは1つだけです。残りはここまでの組み合わせで、fleama のカートを完成させます。
- action のユニオン型で、カートにできることを一覧にする
- reducer に決まりごとを集める
- dispatch で「起きたこと」だけを送る
- 合計金額と合計点数を、状態から計算して出す
材料を持たない action もある
新しいのはここです。「カートを空にする」に材料は要りません。その場合は type だけの action を足します。
type CartAction =
| { type: "ADD"; item: Item }
| { type: "REMOVE"; id: string }
| { type: "CHANGE_QTY"; id: string; qty: number }
| { type: "CLEAR" };reducer 側も1行です。
case "CLEAR":
return [];合計は state に持たない
合計金額を useState で持って、追加のたびに足していく書き方をしたくなります。やめてください。カートの中身と合計という同じことを表す値が2つになり、片方だけ古いという事故が必ず起きます。
合計はカートから毎回計算します。
const count = cart.reduce((sum, line) => sum + line.qty, 0);
const total = cart.reduce((sum, line) => sum + line.item.price * line.qty, 0);計算し直すのが無駄に見えても、数十行の配列なら人の目には一瞬です。状態は1つ、残りはそこから作るが原則です。
売り切れは入れられない
fleama の商品には status があります。売り切れの商品はカートに入れられないようにします。ボタンそのものを押せなくするのが素直です。
<button disabled={item.status === "sold"}>カートに入れる</button>reducer 側で弾く手もありますが、押せるのに何も起きないボタンは、使う人には壊れて見えます。できないことは、できない見た目にするほうが親切です。
演習
カートを完成させます。追加、数量変更、削除、全消し、合計の表示までを通します。