React Context Pattern
Share state across the component tree without prop drilling using React Context
When to Use
- Theme, locale, current user, or feature flags need to be accessible throughout the app
- Prop drilling through 3+ intermediate components that do not use the data
- State that changes infrequently (avoid for high-frequency updates without optimization)
- Building component libraries that need implicit configuration
Instructions
- Create a typed context with
createContext:interface AuthContextValue {
user: User | null;
signOut: () => void;
}
const AuthContext = createContext<AuthContextValue | null>(null);
- Create a Provider component that holds the state:
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null);
return (
<AuthContext.Provider value={{ user, signOut: () => setUser(null) }}>
{children}
</AuthContext.Provider>
);
}
- Create a safe consumer hook that throws when used outside the provider:
export function useAuth(): AuthContextValue {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be used within AuthProvider');
return ctx;
}
- Place the provider at the appropriate level in the tree (app root, route boundary, or feature boundary).
Details
Context provides a mechanism for passing values through the component tree without prop drilling. It is not a replacement for state management — it is a mechanism for making existing state accessible.
Performance: All consumers of a context re-render when the context value changes. Split contexts by update frequency: { theme, toggleTheme } in one context, { user, signOut } in another.
Context vs prop drilling vs state management:
- Prop drilling: explicit, easy to trace, burdensome for deep trees
- Context: implicit, harder to trace, good for cross-cutting concerns
- State management (Zustand/Redux): explicit subscriptions, selectors, derived state
React 19: use(Context) can be called conditionally and inside if blocks, unlike useContext. Equivalent behavior, more flexibility.
Source
https://patterns.dev/react/context-pattern
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.
1---2name: react-context-pattern3description: React Context Pattern4---5# React Context Pattern67> Share state across the component tree without prop drilling using React Context89## When to Use1011- Theme, locale, current user, or feature flags need to be accessible throughout the app12- Prop drilling through 3+ intermediate components that do not use the data13- State that changes infrequently (avoid for high-frequency updates without optimization)14- Building component libraries that need implicit configuration1516## Instructions17181. Create a typed context with `createContext`:19 ```typescript20 interface AuthContextValue {21 user: User | null;22 signOut: () => void;23 }24 const AuthContext = createContext<AuthContextValue | null>(null);25 ```262. Create a Provider component that holds the state:27 ```typescript28 export function AuthProvider({ children }: { children: React.ReactNode }) {29 const [user, setUser] = useState<User | null>(null);30 return (31 <AuthContext.Provider value={{ user, signOut: () => setUser(null) }}>32 {children}33 </AuthContext.Provider>34 );35 }36 ```373. Create a safe consumer hook that throws when used outside the provider:38 ```typescript39 export function useAuth(): AuthContextValue {40 const ctx = useContext(AuthContext);41 if (!ctx) throw new Error('useAuth must be used within AuthProvider');42 return ctx;43 }44 ```454. Place the provider at the appropriate level in the tree (app root, route boundary, or feature boundary).4647## Details4849Context provides a mechanism for passing values through the component tree without prop drilling. It is not a replacement for state management — it is a mechanism for making existing state accessible.5051**Performance:** All consumers of a context re-render when the context value changes. Split contexts by update frequency: `{ theme, toggleTheme }` in one context, `{ user, signOut }` in another.5253**Context vs prop drilling vs state management:**5455- Prop drilling: explicit, easy to trace, burdensome for deep trees56- Context: implicit, harder to trace, good for cross-cutting concerns57- State management (Zustand/Redux): explicit subscriptions, selectors, derived state5859**React 19:** `use(Context)` can be called conditionally and inside `if` blocks, unlike `useContext`. Equivalent behavior, more flexibility.6061## Source6263https://patterns.dev/react/context-pattern6465## Process66671. Read the instructions and examples in this document.682. Apply the patterns to your implementation, adapting to your specific context.693. Verify your implementation against the details and edge cases listed above.7071## Harness Integration7273- **Type:** knowledge — this skill is a reference document, not a procedural workflow.74- **No tools or state** — consumed as context by other skills and agents.7576## Success Criteria7778- The patterns described in this document are applied correctly in the implementation.79- Edge cases and anti-patterns listed in this document are avoided.