Roadmap › React (with Hooks, React 19 & Next.js basics) › Module: Hooks in Depth
Lessons in this course (17)
9. useContext and useReducer
Intermediate★ Must knowLesson 9 of 17
jsx
const AuthContext = createContext(null);
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const value = useMemo(() => ({ user, login: setUser, logout: () => setUser(null) }), [user]);
return <AuthContext value={value}>{children}</AuthContext>; // React 19: <Context> as provider (older: <AuthContext.Provider>)
}
const useAuth = () => {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error("useAuth must be used inside AuthProvider");
return ctx;
};
// useReducer: complex state transitions in one place
function cartReducer(state, action) {
switch (action.type) {
case "add": return { ...state, items: [...state.items, action.item] };
case "remove": return { ...state, items: state.items.filter(i => i.id !== action.id) };
case "clear": return { ...state, items: [] };
default: throw new Error(`Unknown action ${action.type}`);
}
}
const [cart, dispatch] = useReducer(cartReducer, { items: [] });
dispatch({ type: "add", item: { id: 7, name: "Mouse", price: 900 } });Context avoids prop drilling for app-wide values (theme, auth, locale). Every consumer re-renders when the context value changes — split contexts, memoise the value, or use a state library for frequently changing global state.