TSX
Public
Typed Context Reducer Pattern
Combine React context and useReducer with typed actions and a safe custom hook.
#react
#context
#reducer
#typescript
TSX
'use client';
import {
createContext,
type ReactNode,
useContext,
useReducer,
} from 'react';
type CartState = {
itemCount: number;
};
type CartAction =
| { type: 'add'; quantity: number }
| { type: 'clear' };
const CartContext = createContext<{
state: CartState;
dispatch: React.Dispatch<CartAction>;
} | null>(null);
function cartReducer(
state: CartState,
action: CartAction,
): CartState {
switch (action.type) {
case 'add':
return {
itemCount: state.itemCount + action.quantity,
};
case 'clear':
return { itemCount: 0 };
}
}
export function CartProvider({ children }: { children: ReactNode }) {
const [state, dispatch] = useReducer(cartReducer, {
itemCount: 0,
});
return (
<CartContext.Provider value={{ state, dispatch }}>
{children}
</CartContext.Provider>
);
}
export function useCart() {
const context = useContext(CartContext);
if (!context) {
throw new Error('useCart must be used inside CartProvider.');
}
return context;
}