I'm trying to create a dark mode toggle in React and TailwindCSS for my web page, and have been following this tutorial: https://omerduraker.medium.com/dark-and-light-mode-using-react-tailwind-css-58bb8f988080.
The tutorial worked fine, however when I tried to change the default behaviour to default to dark mode rather than light mode, I have been running into issues, I presume with states not updating? The tutorial uses localStorage to save the chosen colour mode preference, however when you first visit the page, as there is no localStorage value present, it only retrieves the value 'undefined' meaning that the application defaults to light mode. The issue primarily pertains to behaviour on first loading of the website, once you have a valid localStorage value, it works fine!
Here is the code I have been trying to use to override this behaviour, but while I can override the page to dark mode, my toggle switch is staying stuck in the position it would be if the page were in light mode. I have provided a screenshot highlighting the issue below. Can anyone see what I'm doing wrong? Thanks!
This should show a white moon icon, not a black sun.
Looking in React developer tools, it appears the state is not updating. The state highlighted should be true, but is unfortunately showing false for some reason.
useDarkMode.tsx:
import React, { useEffect, useState } from "react";
export default function useDarkMode() {
const [theme, setTheme] = useState(localStorage.theme);
if (typeof theme === 'undefined') {
setTheme('dark');
}
const colourTheme = theme === 'dark' ? 'light' : ('light' ? 'dark' : 'light');
useEffect(() => {
const root = window.document.documentElement;
root.classList.remove(colourTheme);
root.classList.add(typeof theme === 'undefined' ? 'dark' : theme);
localStorage.setItem('theme', typeof theme === 'undefined' ? 'dark' : theme);
}, [theme, colourTheme]);
return [colourTheme, setTheme] as any;
}
nav.tsx
export default function Nav(props: any) {
const [colourtheme, setTheme] = useDarkMode();
const [isDarkMode, setDarkMode] = useState(
colourtheme === "dark" ? true : false
);
....
switcher.tsx
import React, { useState } from 'react';
import { DarkModeSwitch } from 'react-toggle-dark-mode';
export default function Switcher(props: any) {
function toggleDarkMode(checked: boolean):void {
props.functions.setTheme(props.functions.colourtheme);
props.functions.setDarkMode(checked);
}
return (
<div className={`flex flex-col items-center w-auto ${props.className}`}>
<DarkModeSwitch
style={{ }}
checked={props.functions.isDarkMode}
onChange={toggleDarkMode}
size={25}
/>
</div>
);
};