Write a cart reducer with add, remove, and set quantity, and a CartProvider to share it
Write CartContext.jsx for a tea shop. The cart is an array of lines, { id, name, price, quantity }, in the order they were first added.
Export cartReducer(cart, action), a pure function that never changes cart or its lines, for three actions. Any other type throws an Error with the message Unknown action: and the type, like Unknown action: bought.
dispatch({ type: "added", tea: { id: "chai", name: "Chai", price: 3 } });
// a new line with quantity 1, or one more of a line that's there (at most 10)
dispatch({ type: "removed", id: "chai" });
// drop that line
dispatch({ type: "quantityChanged", id: "chai", quantity: 4 });
// set that line's quantity: below 1 drops the line, above 10 makes it 10
Export CartProvider, which takes children and an optional initialCart (empty by default), and two hooks: useCart() returns the cart and useCartDispatch() returns dispatch. With no CartProvider above, they throw useCart must be used inside a CartProvider and useCartDispatch must be used inside a CartProvider. Components that only call useCartDispatch() must not render again when the cart changes.
import { createContext, useContext, useReducer } from "react";
const CartContext = createContext(null);
export function cartReducer(cart, action) {
// Handle "added", "removed", and "quantityChanged".
return cart;
}
export function CartProvider({ children, initialCart = [] }) {
const [cart, dispatch] = useReducer(cartReducer, initialCart);
return <CartContext value={{ cart, dispatch }}>{children}</CartContext>;
}
export function useCart() {
return useContext(CartContext).cart;
}
export function useCartDispatch() {
return useContext(CartContext).dispatch;
}
- added makes a line, then counts it up, without changing the old cart
- removed and quantityChanged change one line and keep the rest
- a quantity stays between 1 and 10
- throws on an unknown action
- the provider shares one cart between distant components
- starts from initialCart
- the hooks throw a helpful error outside a CartProvider
- components that only dispatch don't render when the cart changes
The answer
Write it yourself first. Then compare it with a reference solution and the checks it passes.
Checking your sign-in…