Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Automatic browser theme detection (and support) using React 16 context and hooks
import React from 'react';
import { Card } from '../components';
import { ThemeContext } from '../util';
class Application extends React.Component {
static contextType = ThemeContext;
toggleTheme = () => {
const newTheme = this.state.theme === 'light' ? 'dark' : 'light';
this.setState(state => ({ theme: newTheme }));
localStorage.setItem('theme', newTheme);
};
getThemePreference = () => {
const themeFromStorage = localStorage.getItem('theme');
const browserColorScheme = scheme =>
matchMedia(`(prefers-color-scheme: ${scheme})`).matches;
if (!themeFromStorage) {
return browserColorScheme('dark') ? 'dark' : 'light';
}
return themeFromStorage === 'light' || themeFromStorage === 'dark'
? themeFromStorage
: 'light';
};
state = {
theme: this.getThemePreference(),
toggleTheme: this.toggleTheme
};
render() {
return (
<ThemeContext.Provider value={this.state}>
<div>
<h1>The current theme is: {this.state.theme}</h1>
<Card />
</div>
</ThemeContext.Provider>
);
}
}
export default Application;
import React, { useContext } from 'react';
import { ThemeContext } from '../util';
const Card = props => {
const context = useContext(ThemeContext);
return (
<div>
<p>This is a card. Your current theme is: {context.theme}</p>
<button onClick={context.toggleTheme}>Change Theme</button>
</div>
);
};
export default Card;
import { createContext } from 'react';
const ThemeContext = createContext({ theme: 'light', toggleTheme: () => {} });
export default ThemeContext;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.