0
# Context API
1
2
Full React context system for sharing data between components without explicit prop passing.
3
4
## Capabilities
5
6
### Create Context
7
8
Creates a context object with Provider and Consumer components for sharing data across the component tree.
9
10
```javascript { .api }
11
/**
12
* Create a context object for sharing data between components
13
* @param {any} defaultValue - Default value when no Provider is found
14
* @returns {Context} Context object with Provider and Consumer components
15
*/
16
function createContext(defaultValue);
17
18
/**
19
* Context object with Provider and Consumer components
20
*/
21
interface Context<T> {
22
/**
23
* Provider component that supplies context value to descendants
24
*/
25
Provider: ComponentClass<{
26
value: T;
27
children?: ComponentChildren;
28
}>;
29
30
/**
31
* Consumer component that consumes context value
32
*/
33
Consumer: ComponentClass<{
34
children: (value: T) => ComponentChildren;
35
}>;
36
}
37
```
38
39
**Usage Examples:**
40
41
```javascript
42
import { createContext, Component } from 'preact-compat';
43
44
// Create context
45
const ThemeContext = createContext('light');
46
47
// Provider component
48
class ThemeProvider extends Component {
49
state = { theme: 'dark' };
50
51
toggleTheme = () => {
52
this.setState(prevState => ({
53
theme: prevState.theme === 'light' ? 'dark' : 'light'
54
}));
55
};
56
57
render() {
58
return (
59
<ThemeContext.Provider value={{
60
theme: this.state.theme,
61
toggleTheme: this.toggleTheme
62
}}>
63
{this.props.children}
64
</ThemeContext.Provider>
65
);
66
}
67
}
68
69
// Consumer component
70
function ThemedButton() {
71
return (
72
<ThemeContext.Consumer>
73
{({ theme, toggleTheme }) => (
74
<button
75
className={`btn btn-${theme}`}
76
onClick={toggleTheme}
77
>
78
Current theme: {theme}
79
</button>
80
)}
81
</ThemeContext.Consumer>
82
);
83
}
84
85
// App structure
86
function App() {
87
return (
88
<ThemeProvider>
89
<div>
90
<h1>My App</h1>
91
<ThemedButton />
92
</div>
93
</ThemeProvider>
94
);
95
}
96
```
97
98
### Multiple Contexts
99
100
```javascript
101
import { createContext } from 'preact-compat';
102
103
// Multiple contexts for different concerns
104
const UserContext = createContext(null);
105
const SettingsContext = createContext({});
106
107
function App() {
108
const user = { name: 'John', id: 1 };
109
const settings = { darkMode: true, language: 'en' };
110
111
return (
112
<UserContext.Provider value={user}>
113
<SettingsContext.Provider value={settings}>
114
<Dashboard />
115
</SettingsContext.Provider>
116
</UserContext.Provider>
117
);
118
}
119
120
function Dashboard() {
121
return (
122
<UserContext.Consumer>
123
{user => (
124
<SettingsContext.Consumer>
125
{settings => (
126
<div className={settings.darkMode ? 'dark' : 'light'}>
127
<h1>Welcome, {user.name}!</h1>
128
</div>
129
)}
130
</SettingsContext.Consumer>
131
)}
132
</UserContext.Consumer>
133
);
134
}
135
```
136
137
### Context with Class Components
138
139
```javascript
140
import { createContext, Component } from 'preact-compat';
141
142
const ApiContext = createContext();
143
144
class ApiProvider extends Component {
145
state = {
146
data: null,
147
loading: false,
148
error: null
149
};
150
151
fetchData = async (url) => {
152
this.setState({ loading: true, error: null });
153
try {
154
const response = await fetch(url);
155
const data = await response.json();
156
this.setState({ data, loading: false });
157
} catch (error) {
158
this.setState({ error, loading: false });
159
}
160
};
161
162
render() {
163
return (
164
<ApiContext.Provider value={{
165
...this.state,
166
fetchData: this.fetchData
167
}}>
168
{this.props.children}
169
</ApiContext.Provider>
170
);
171
}
172
}
173
174
class DataComponent extends Component {
175
componentDidMount() {
176
// Access context via contextType (not supported in preact-compat)
177
// Use Consumer pattern instead
178
}
179
180
render() {
181
return (
182
<ApiContext.Consumer>
183
{({ data, loading, error, fetchData }) => (
184
<div>
185
<button onClick={() => fetchData('/api/data')}>
186
Load Data
187
</button>
188
{loading && <p>Loading...</p>}
189
{error && <p>Error: {error.message}</p>}
190
{data && <pre>{JSON.stringify(data, null, 2)}</pre>}
191
</div>
192
)}
193
</ApiContext.Consumer>
194
);
195
}
196
}
197
```
198
199
## Types
200
201
```javascript { .api }
202
interface Context<T> {
203
Provider: ComponentClass<ProviderProps<T>>;
204
Consumer: ComponentClass<ConsumerProps<T>>;
205
}
206
207
interface ProviderProps<T> {
208
value: T;
209
children?: ComponentChildren;
210
}
211
212
interface ConsumerProps<T> {
213
children: (value: T) => ComponentChildren;
214
}
215
216
type ContextType<C extends Context<any>> = C extends Context<infer T> ? T : never;
217
```