Skip to content

Instantly share code, notes, and snippets.

@ryanwarsaw
Created August 16, 2019 14:04
Show Gist options
  • Save ryanwarsaw/5a1384a2941b1d1ce143242f8099795f to your computer and use it in GitHub Desktop.
Save ryanwarsaw/5a1384a2941b1d1ce143242f8099795f to your computer and use it in GitHub Desktop.
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