Context provides a way to pass data through the component tree without having to pass props down manually at every level. It’s designed to share data that can be considered “global” for a tree of Preact components.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/preactjs/preact/llms.txt
Use this file to discover all available pages before exploring further.
When to Use Context
Context is ideal for sharing data that is needed by many components at different nesting levels:- Current authenticated user
- Theme preferences (dark/light mode)
- Language/locale settings
- UI state (modals, notifications)
Creating Context
UsecreateContext to create a new context object. It accepts a default value that’s used when a component doesn’t have a matching Provider above it.
Implementation Details
ThecreateContext function is implemented in src/create-context.js. It returns a special component that acts as both Provider and Consumer:
src/create-context.js:6-60
Provider Component
Every Context object comes with a Provider component that allows consuming components to subscribe to context changes.import { createContext } from 'preact';
import { useState } from 'preact/hooks';
const ThemeContext = createContext('light');
function App() {
const [theme, setTheme] = useState('dark');
return (
<ThemeContext.Provider value={theme}>
<Toolbar />
<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
Toggle Theme
</button>
</ThemeContext.Provider>
);
}
const ThemeContext = createContext('light');
const UserContext = createContext(null);
function App() {
return (
<ThemeContext.Provider value="dark">
<UserContext.Provider value={{ name: 'Alice', role: 'admin' }}>
<Dashboard />
</UserContext.Provider>
</ThemeContext.Provider>
);
}
import { createContext } from 'preact';
import { useState } from 'preact/hooks';
const AuthContext = createContext(null);
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = (username, password) => {
// Login logic
setUser({ username });
};
const logout = () => {
setUser(null);
};
const value = {
user,
login,
logout
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
Consuming Context
There are two ways to consume context in Preact:- useContext Hook (Recommended)
- Consumer Component
The Reference:
useContext hook is the recommended way to consume context in function components:How useContext Works
TheuseContext hook is implemented in hooks/src/index.js. It reads the context value from the current component’s context and subscribes to updates:hooks/src/index.js:367-385Practical Examples
Best Practices
// Good: Separate contexts
const ThemeContext = createContext();
const AuthContext = createContext();
const NotificationContext = createContext();
// Less ideal: One giant context
const AppContext = createContext({
theme: 'light',
user: null,
notifications: []
});
import { createContext } from 'preact';
import { useContext } from 'preact/hooks';
const UserContext = createContext(null);
export function useUser() {
const context = useContext(UserContext);
if (!context) {
throw new Error('useUser must be used within UserProvider');
}
return context;
}
import { useMemo, useState } from 'preact/hooks';
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
// Good: Memoize the value object
const value = useMemo(
() => ({
user,
login: () => { /* ... */ },
logout: () => { /* ... */ }
}),
[user]
);
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
}
Performance Considerations
Context updates cause all consuming components to re-render. Here are strategies to optimize:- Split Contexts
- Memoize Context Values
- Component Splitting
Split frequently changing values into separate contexts:Now components that only need theme won’t re-render when user changes.
Next Steps
Hooks
Learn more about hooks including useContext
Refs
Work with DOM references and forward refs