// Encapsulate context + hook in a moduleconst Ctx = createContext(null);
exportfunction useMyContext() {
const ctx = useContext(Ctx);
if (!ctx) thrownew Error('Missing Provider');
return ctx;
}
example
import { createContext, useContext, useState } from'react';
const CartContext = createContext(null);
exportfunction CartProvider({ children }) {
const [items, setItems] = useState([]);
function addItem(product) {
setItems(prev => [...prev, { ...product, qty: 1 }]);
}
function removeItem(id) {
setItems(prev => prev.filter(item => item.id !== id));
}
const totalItems = items.reduce((sum, i) => sum + i.qty, 0);
return (
<CartContext.Provider value={{ items, addItem, removeItem, totalItems }}>
{children}
</CartContext.Provider>
);
}
exportfunction useCart() {
const context = useContext(CartContext);
if (!context) {
thrownew Error('useCart must be used within a CartProvider');
}
return context;
}
Note Exporting a custom hook that throws when the Provider is missing catches mistakes early and gives a clear error message instead of undefined values that silently break downstream.
Note This pattern provides Redux-like state management with built-in React APIs. Splitting state and dispatch into separate contexts prevents components that only dispatch actions from re-rendering when state changes.