Dark Mode 2.0 : With Local Storage

In my last post I covered a simple dark mode toggle with react and tailwind. The toggle was held in state and would reset to light mode upon refreshes and traveling to different routes; not very practical. We don’t want our user to have to continuously select dark mode as they travel through our site. A way we can work around this issue is creating a dark mode theme, stored in our localStorage object. localStorage persists through refreshes so the users’ preference will be maintained while they use the site. If you are at anytime feeling a little lost refer to my last post for reference! Let’s get into it.

function App() {const [checked, setChecked] = useState(false);const root = window.document.documentElementconst lightTheme = "light"const darkTheme = "dark"let theme;

First we are going to established some variables. Out checked and setChecked state is for out toggle switch. Now, I am actually using a package called react-switch that comes with customizable switch toggles and I would highly recommend using. Root is out document we are going to be adding our classes on and theme we will use in a minute.

function App() {const [checked, setChecked] = useState(false);const root = window.document.documentElementconst lightTheme = "light"const darkTheme = "dark"let theme;if (localStorage) {theme = localStorage.getItem("theme")}if (theme === lightTheme || theme === darkTheme) {root.classList.add(theme);} else {root.classList.add(lightTheme)}

Next we are saying if localStorage exists, then theme is going to equal our localStorage theme value. We are then checking if theme is equal to dark or light, we are going to add either one to our document class list, and if neither are true, we are going to default to light mode.

Now that we have that established let’s flesh out our handleChange function that is going to fire when we use our toggle.

const handleChange = () => {if (theme === darkTheme) {root.classList.replace(darkTheme, lightTheme);localStorage.setItem("theme", "light");theme = lightThemesetChecked(false)} else {root.classList.replace(lightTheme, darkTheme)localStorage.setItem("theme", 'dark')setChecked(true)}};

If our theme is equal to dark, we are going to replace our class dark theme with light and change our localStorage respectively. We want to set theme to light at the end for our if statement we created in the second code block. We are also changing the state of out toggle to render checked and unchecked. The else statement does the exact opposite.

checked={localStorage.getItem("theme") === 'dark' ? true : false}

Lastly, we are making sure our checked value on our switch component stays in line with our localStorage value when the page refreshes. All done!