Skip to content

Instantly share code, notes, and snippets.

@michal-wrzosek
Last active October 22, 2019 16:41
Show Gist options
  • Save michal-wrzosek/d6a232f977d704fb12c9d2f6e076301b to your computer and use it in GitHub Desktop.
Save michal-wrzosek/d6a232f977d704fb12c9d2f6e076301b to your computer and use it in GitHub Desktop.
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type Theme = {
fontColor: string;
};
const theme = {
fontColor: 'red',
};
const ThemeContext = React.createContext({ theme });
type ThemeProviderProps = {
theme: Theme;
};
const ThemeProvider: React.FC<ThemeProviderProps> = ({ theme, children }) => (
<ThemeContext.Provider value={{ theme }}>{children}</ThemeContext.Provider>
);
type WithThemeProps = {
theme: Theme;
};
// HOC
const withTheme = <P extends object>(
Component: React.ComponentType<P>,
): React.FC<Omit<P, keyof WithThemeProps>> => props => (
<ThemeContext.Consumer>
{({ theme }) => <Component {...props as P} theme={theme} />}
</ThemeContext.Consumer>
);
// Component
type ListProps = {
items: string[];
theme: Theme;
};
const List = ({ items, theme }: ListProps) => (
<ul style={{ color: theme.fontColor }}>
{items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
);
// Wrapping Component in HOC
const ListWithTheme = withTheme(List);
const App = () => (
<ThemeProvider theme={theme}>
<ListWithTheme items={['one', 'two', 'three']} />
</ThemeProvider>
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment