Global state without prop drilling. Providers sit at the top; any descendant reads the value with useContext.
Change theme here. Both components below consume the same context — no props passed!
// Step 1: Create context (with TypeScript type + default)
const ThemeCtx = createContext<ThemeContextType>(defaultValue);
// Step 2: Provide it high in the tree
<ThemeCtx.Provider value={{ theme, setTheme }}><App /></ThemeCtx.Provider>
// Step 3: Custom hook for cleaner DX + error guard
function useTheme() {
const ctx = useContext(ThemeCtx);
if (!ctx) throw new Error("Missing Provider");
return ctx;
}
// Step 4: Consume anywhere in the tree
const { theme, setTheme } = useTheme();// Combine for complex state management
const [state, dispatch] = useReducer(reducer, init);
<AppContext.Provider value={{ state, dispatch }}>
<App />
</AppContext.Provider>
// In any child:
const { state, dispatch } = useAppContext();
dispatch({ type: "INCREMENT" });