Coding exercise: create a shopping cart in React.
Model answer
A reducer suits a cart well because it has several actions on one piece of state. Store items by id with a quantity, and work out the total during render.
function cartReducer(state, action) {
switch (action.type) {
case 'add': {
const found = state.find((i) => i.id === action.item.id);
return found
? state.map((i) => (i.id === found.id ? { ...i, qty: i.qty + 1 } : i))
: [...state, { ...action.item, qty: 1 }];
}
case 'remove': return state.filter((i) => i.id !== action.id);
case 'qty': return state.map((i) => (i.id === action.id ? { ...i, qty: Math.max(1, action.qty) } : i));
default: return state;
}
}
function Cart({ catalog }) {
const [cart, dispatch] = useReducer(cartReducer, []);
const total = cart.reduce((sum, i) => sum + i.price * i.qty, 0);
return (
<>
{catalog.map((p) => <button key={p.id} onClick={() => dispatch({ type: 'add', item: p })}>Add {p.name}</button>)}
<ul>{cart.map((i) => (
<li key={i.id}>{i.name} × {i.qty}
<button onClick={() => dispatch({ type: 'remove', id: i.id })}>Remove</button></li>))}</ul>
<p>Total: {total.toFixed(2)}</p>
</>
);
}To share the cart across pages, put the reducer in a context provider and save it to localStorage. Prices must be checked again on the server at checkout.
Tips
- Money maths: use whole minor units (paise or cents) in real shops to avoid rounding errors.
Practise it yourself in the React and Angular code playground.
Learn this topic
React.js Full Course: Beginner to Advanced .
Sign in to add your own answer.
More questions
- Coding exercise: build a Todo application in React.
- Coding exercise: create a search box with debounce in React.
- Coding exercise: fetch API data and display it in a table in React.
- Coding exercise: implement pagination in React.
- Coding exercise: create a login form with validation in React.
- Coding exercise: build a parent-child communication example in React.