A shopping cart reducer that manages items, quantities, and totals as a single state object.
// cartReducer.js
export const initialState = { items: [], total: 0 };
export function cartReducer(state, action) {
switch (action.type) {
case 'ADD_ITEM': {
const existing = state.items.find(i => i.id === action.item.id);
const items = existing
? state.items.map(i =>
i.id === action.item.id
? { ...i, qty: i.qty + 1 }
: i
)
: [...state.items, { ...action.item, qty: 1 }];
return { items, total: items.reduce((s, i) => s + i.price * i.qty, 0) };
}
case 'REMOVE_ITEM': {
const items = state.items.filter(i => i.id !== action.id);
return { items, total: items.reduce((s, i) => s + i.price * i.qty, 0) };
}
case 'CLEAR':
return initialState;
default:
return state;
}
}
// Cart.jsx
import { useReducer } from 'react';
import { cartReducer, initialState } from './cartReducer';
function Cart() {
const [cart, dispatch] = useReducer(cartReducer, initialState);
const add = item => dispatch({ type: 'ADD_ITEM', item });
const remove = id => dispatch({ type: 'REMOVE_ITEM', id });
const clear = () => dispatch({ type: 'CLEAR' });
return (
<div>
<p>Total: ${cart.total.toFixed(2)}</p>
{cart.items.map(item => (
<div key={item.id}>
{item.name} × {item.qty}
<button onClick={() => remove(item.id)}>Remove</button>
</div>
))}
<button onClick={clear}>Clear cart</button>
</div>
);
}
All Comments