React Dark Mode Handler

392 Views Asked by At

I have the following code inside my App component.

const darkMode = window.matchMedia('(prefers-color-scheme: dark)');
const [isDarkMode, setIsDarkMode] = React.useState(darkMode.matches);

const darkModeChangeHandler = (e) => {
    console.log('e.matches', e.matches);
    setIsDarkMode(e.matches);
};
darkMode.addListener(darkModeChangeHandler);

React.useEffect(() => {
    console.log('dark mode', isDarkMode);
    if (isDarkMode)
        require('bootswatch/dist/darkly/bootstrap.min.css');
    else
        require('bootswatch/dist/flatly/bootstrap.min.css');
        return () => {
        darkMode.removeListener(darkModeChangeHandler);
    };
}, [isDarkMode]);

When I start out in light mode, then go into system settings and turn on dark mode, the darkly css is loaded, but when I turn off dark mode the css doesn't update. Same thing happens in the opposite when I start out in dark mode.

You can see I'm logging the value of isDarkMode and it's updated every time I turn on/off dark mode. Can anyone explain why the css is only changing the first time? Is there a better way of handling the updating of css?

1

There are 1 best solutions below

0
On

You probably don't need a Handler here - I'm assuming you'll always want to use one of the two Bootstrap variants from Bootswatch - so you can just add the following code to the <head> section of your html:

<!-- Bootstrap CSS -->
<!-- Inform modern browsers that this page supports both dark and light color schemes -->
<meta name="color-scheme" content="light dark">
<!-- Load the alternate CSS first ... -->
<link rel="stylesheet" href="bootswatch/dist/darkly/bootstrap.min.css" media="(prefers-color-scheme: dark)">
<!-- ... and then the primary CSS last -->
<link rel="stylesheet" href="bootswatch/dist/flatly/bootstrap.min.css" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)">

Have a look at https://vinorodrigues.github.io/bootstrap-dark/readme.html#bootstrap-night for a full writeup on this ... there are bits about fallbacks etc., but since you're using browsers that support React you probably don't need these.