Shopping CartLoading saved progress…

Shopping Cart

Build a small shopping cart as a single React component. Each line has a name, a − / qty / + stepper, a live line total, and a Remove button; below the list a grand total sums every line. The whole thing is one items array in state — every number on screen is derived from it, so you never store a total you have to keep in sync by hand.

Task

The starter App.tsx renders three rows and a grand total from a fixed initialItems array, but the buttons do nothing. Make it interactive:

  1. Hold the rows in state. Move initialItems into useState so edits re-render.
  2. Stepper. + adds one to that row's qty; subtracts one but never goes below 1 (use Math.max(1, qty - 1)). Update the array immutably.
  3. Remove. The Remove button drops that row from items.
  4. Derive the money. Each line total is price * qty; the grand total is the sum of the line totals. Format everything as $X.XX.
  5. Empty state. When the last row is removed, show Your cart is empty and a $0.00 total.

Examples

  • Keyboard $49.00 x1, Mouse $25.50 x2, Monitor $199.99 x1 gives lines $49.00, $51.00, $199.99 and a grand total of $299.99.
  • Press + on Mouse and its qty becomes 3, its line becomes $76.50, and the grand total becomes $325.49.
  • Press on Keyboard while qty is 1 and nothing happens (min is 1). Remove is how you delete a row.
  • Remove all three rows and you get Your cart is empty with a $0.00 total.

Notes

  • One source of truth. Keep only items in state. Line totals and the grand total are computed on each render — don't store them.
  • Update immutably. Return a new array from map/filter; never mutate an item in place, or React won't see the change.
  • Clamp, don't delete, at 1. stops at 1; deletion is a separate action (Remove).
  • Format once. A tiny money(n) helper (n.toFixed(2)) keeps every price formatted the same way.
Loading editor…
Loading preview…