Skip to content

Commit e0cff22

Browse files
committed
typed context api implementation
1 parent c5a9869 commit e0cff22

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React from 'react';
2+
declare module 'react' {
3+
const createContext: <T>(defaultValue: T) => {
4+
Consumer: React.ComponentClass<{ children: (value: T) => React.ReactNode }>;
5+
Provider: React.ComponentClass<{ value: T }>;
6+
};
7+
}
8+
9+
// Context
10+
const themes = {
11+
dark: {
12+
color: 'black', backgroundColor: 'white',
13+
} as React.CSSProperties,
14+
light: {
15+
color: 'white', backgroundColor: 'black',
16+
} as React.CSSProperties,
17+
};
18+
19+
type Theme = { theme: React.CSSProperties; toggleTheme?: () => void };
20+
const ThemeContext = React.createContext<Theme>({ theme: themes.light });
21+
22+
// Provider
23+
interface State { theme: Theme['theme']; }
24+
export class App extends React.Component<{}, State> {
25+
readonly state: State = { theme: themes.light };
26+
27+
toggleTheme = () => {
28+
this.setState(state => ({
29+
theme: state.theme === themes.light ? themes.dark : themes.light,
30+
}));
31+
}
32+
33+
render() {
34+
const { theme } = this.state;
35+
const { toggleTheme } = this;
36+
return (
37+
<ThemeContext.Provider value={{ theme, toggleTheme }} >
38+
<ToggleThemeButton />
39+
</ThemeContext.Provider>
40+
);
41+
}
42+
}
43+
44+
// Consumer
45+
interface ThemedButtonProps { }
46+
47+
function ToggleThemeButton(props: ThemedButtonProps) {
48+
return (
49+
<ThemeContext.Consumer>
50+
{({ theme, toggleTheme }) => <button style={theme} onClick={toggleTheme} {...props} />}
51+
</ThemeContext.Consumer>
52+
);
53+
}

0 commit comments

Comments
 (0)