Home > Blockchain >  Persist user theme in localStorage on reload
Persist user theme in localStorage on reload

Time:10-10

I am building a weather app with React & Tailwind & I am trying to save the users theme preference to local storage but it isn't persisting on reload

Here's my code. I don't know what I am doing wrong. I can set it switching in the storage panel in dev tools and it is saving it there but it isn't setting it to the correct theme on page reload.

function App() {
  const [darkMode, setDarkMode] = useState(false);

  //Call from local Storage
  useEffect(() => {
    const storedPreference = localStorage.getItem('prefersDarkMode');
    if (storedPreference) {
      setDarkMode(JSON.parse(storedPreference));
    }
  }, []);

  //Set to Local Storage
  useEffect(() => {
    if (darkMode) {
      localStorage.setItem('prefersDarkMode', 'true');
      document.body.classList.add('dark');
    } else {
      localStorage.setItem('prefersDarkMode', 'false');
      document.body.classList.remove('dark');
    }
  }, [darkMode]);
  return (
    <div className={darkMode ? 'flex flex-col min-h-screen bg-gray-800' : 'bg-neutral-50 flex flex-col min-h-screen'}>
      <Header>
        <button
          onClick={() => {
            setDarkMode(!darkMode);
          }}
        >
          {darkMode ? <BsFillSunFill className="fill-neutral-100 text-2xl" /> : <BsFillMoonFill className="fill-gray-700 text-2xl" />}
        </button>
      </Header>
      <ToastContainer theme={darkMode ? 'dark' : 'light'} />
      <Footer />
    </div>
  );
}

export default App;

CodePudding user response:

Here what you can improve/try:

useEffect(() => {
    localStorage.setItem("prefersDarkMode", darkMode ? "true" : "false");

    darkMode
      ? document.body.classList.add("dark")
      : document.body.classList.remove("dark");
  }, [darkMode]);
<button
     onClick={() => {
        setDarkMode((previousState) => !previousState);
      }}>

Hope this can help!

CodePudding user response:

The problem I have seen in your codes is ..

the other useEffect initially calls the localStorage for prefersDarkMode

and the other one is for changing the darkmode state and setting the localStorage

when you reload the page, the darkmode state is always false, because of this

useEffect(() => {
  if (darkMode) {
    localStorage.setItem('prefersDarkMode', 'true');
    document.body.classList.add('dark');
  } else {
    localStorage.setItem('prefersDarkMode', 'false');
    document.body.classList.remove('dark');
  }
}, [darkMode]);

this useEffect will set the prefersDarkMode in your localStorage to false every time you reload

to fix this, i added another state to check if the app already call the localStorage

const [flag, setFlag] = useState(false);

 //Call from local Storage
 useEffect(() => {
   const storedPreference = localStorage.getItem("prefersDarkMode");
   if (storedPreference) {
     setDarkMode(JSON.parse(storedPreference));
   }
   setFlag(true);
 }, []);

 //Set to Local Storage
 useEffect(() => {
   if (flag) {
     localStorage.setItem("prefersDarkMode", darkMode);
     document.body.classList.toggle('dark',darkMode)
   }
 }, [darkMode, flag]);

so that, it won't set it back to default on reload

here is the working example https://codesandbox.io/s/goofy-nash-6fu3c5

  • Related