React useReducer for Complex State

React useReducer for Complex State

React useReducer for Complex State

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