How do I resolve React flash error using dark mode?

Viewed 503

I am using a theme toggler function for dark mode. This function lives inside my src/components/Toggle/Toggle.jsx file, which renders a toggle button that changes the theme. When I reload my page, I get a white flash. I think this is happening because my scripts are not rendering before my HTML doc and it appears the solution is to add a script to my <head>....but I am unsure how to move my Toggle.jsx function out of that component into my <head>...any ideas?

Below is my dark mode function inside my Toggle.jsx...

import "./Toggle.css";
import Icon from "../Icon/Icon";

function Toggle() {
  //optionally parse from localStorage
  const [theme, setTheme] = React.useState(getInitialMode());
  React.useEffect(() => {
    document.documentElement.setAttribute("data-theme", theme);
    localStorage.setItem("theme", JSON.stringify(theme));
  }, [theme]);

  function getInitialMode() {
    const isReturningUser = "theme" in localStorage;
    const savedMode = JSON.parse(localStorage.getItem("theme"));
    const userPrefersDark = getPrefColorScheme();

    // if mode was saved -> dark / light
    if (isReturningUser) {
      return savedMode;
    }
    // if preferred color scheme is dark -> dark
    else if (userPrefersDark) {
      return "dark";
    } else {
      // otherwise -> light
      return "light";
    }
  }

  function getPrefColorScheme() {
    if (!window.matchMedia) return;

    return window.matchMedia("(prefers-color-scheme: dark)").matches;
  }

  return (
    <button
      className="toggle-button"
      onClick={() => {
        setTheme(theme === "light" ? "dark" : "light");
      }}
    >
      <Icon />
    </button>
  );
}

export default Toggle;

1 Answers

I guess easy option would be to set dark mode as default so whenever you refresh the page before the selected theme is loaded your dark theme will load and prevent your screen from flashing

Related