Skip to content

How do you toggle between light and dark themes while current theme is being locally stored?

I am fairly new to react and I’m implementing some new features using Material-UI. I am trying to switch between light and dark themes while the current theme is being locally stored within the browser. I wish to locally store the current theme as the page refreshes. By default, my app loads in the light theme. Before toggling the switch, I verify to see that light theme is in local storage. As I toggle to dark theme, my app changes to its counterpart and the value within my local storage changes just as expected. But when I try to toggle the switch back to light theme, the theme doesn’t change, just my local storage value. I don’t know why.

If someone has a way of tweaking this code to address this problem or suggest a new idea, I greatly appreciate it.

Demo in CodeSandbox


import React, { useState, createContext } from 'react';
import { ThemeProvider } from '@material-ui/core/styles';
import getTheme from '../components/MyThemes';
import Paper from '@material-ui/core/Paper';

export const CustomThemeContext = createContext(
    currentTheme: 'normalTheme',
    setTheme: null,

const CustomThemeProvider = (props) => {
  const { children } = props
  const currentTheme = localStorage.getItem('appTheme') || 'normalTheme'
  const [themeName, _setThemeName] = useState(currentTheme)
  const theme = getTheme(themeName)
  const setThemeName = (name) => {
    localStorage.setItem('appTheme', name)
  const contextValue = {
    currentTheme: themeName,
    setTheme: setThemeName,
  const paperStyle = {
    height: "100vh",

  return (
      <CustomThemeContext.Provider value={contextValue}>
        <ThemeProvider theme={theme}>
          <Paper style={paperStyle}>

export default CustomThemeProvider;


import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import CustomThemeProvider from './contexts/CustomThemeProvider';

      <App />



import React, { useContext } from 'react';
import { makeStyles } from '@material-ui/core/styles';
import { CustomThemeContext } from './contexts/CustomThemeProvider';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Tooltip from '@material-ui/core/Tooltip';
import Typography from '@material-ui/core/Typography';
import BurgerButton from './components/BurgerButton';
import StarButton from './components/StarButton';
import Switch from '@material-ui/core/Switch';
import Button from '@material-ui/core/Button';
import AddCircleIcon from '@material-ui/icons/AddCircle';
import FormControlLabel from '@material-ui/core/FormControlLabel';

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
    width: 'auto',
  title: {
    flexGrow: 1,
  content: {
    flexGrow: 1,
    padding: theme.spacing(3),

export default function App() {
  const classes = useStyles();
  const { currentTheme, setTheme } = useContext(CustomThemeContext);
  const isDark = Boolean(currentTheme === 'darkTheme')

  const handleThemeChange = (event) => {
    const { checked } =
    if (checked) {
    } else {

  switch (checked) {
    case 'darkTheme':
      return setTheme('darkTheme');
    case 'normalTheme':
      return setTheme('normalTheme');
      return null;

  return (
    <div className="App">
      <div className={classes.root}>
        <AppBar position="static" title="Memo App">
            <BurgerButton />
            <Typography variant="h6" className={classes.title}>
              Memo App
            <Tooltip title="Toggle light theme/dark theme">
                control={<Switch checked={isDark} onChange={handleThemeChange} />}
            <StarButton />
          <AddCircleIcon />


import normalTheme from './themes/normalTheme';
import darkTheme from './themes/darkTheme';

const themes = {

export default function getTheme(theme) {
  return themes[theme]



On your ThemeProvider component theme prop, clone the theme object you assign to it and it should work

<ThemeProvider theme={{...theme}}>
  <Paper style={paperStyle}>
10 People found this is helpful