Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

140
Visualizações
How can I make the website theme persists on refresh in React?

I'm currently working in a weather forecast website and I'm trying to apply a theme toggler. I have already set up the functionality, but the chosen theme does not persist when the page is refreshed. Could anyone point out what I'm missing? The console.log shows that the theme inside localStorage changes when I click the theme toggler.

import { WeatherApi } from "./pages/home/weather-api";
import '../src/App.scss'
import { createContext, useEffect, useState } from "react";
import ReactSwitch from "react-switch";

export const ThemeContext = createContext({})

function App() {

  const [theme, setTheme] = useState<string>(localStorage.getItem('theme') || 'light')

  useEffect(() => {

    const localTheme = localStorage.getItem(theme)
    console.log(localTheme)

    if (!localTheme) {
      setTheme("light")
    }

    if (localTheme) {
      if (localTheme === 'light') {
        setTheme('light')
        localStorage.setItem('theme', theme)
        console.log(localStorage)
      }

      if (localTheme === 'dark') {
        setTheme('dark')
        localStorage.setItem('theme', theme)
        console.log(localStorage)
      }
    }
  },[theme])

  const toggleTheme = () => {
    setTheme((currentTheme: any) => (currentTheme === "light" ? "dark" : "light"))
  }

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      <div className="App" id={theme}>
        <WeatherApi />
        <div className="switch">
          <label>{theme === "light" ? "Light mode" : "Dark mode"}</label>
          <ReactSwitch onChange={toggleTheme} checked={theme === "dark"} />
        </div>
      </div>
    </ThemeContext.Provider>
  )

}

export default App;
about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You should load the theme from localStorage and use it as initialState, something like this:

///... more js code
  const intialState = localStorage.getItem('theme') || 'light');
  const [theme, setTheme] = useState<string>('')

  const toggleTheme = () => {
    const newTheme = theme === "light" ? "dark" : "light";
    localStorage.setItem('theme', newTheme);
    setTheme(newTheme);
  }
///... more js code

Note: you don't need to use JSON.stringify or JSON.parse in strings

about 4 years ago · Santiago Trujillo Relatório

0

You already load the theme from localStorage as the default value of the state. The other load from localStorage in useEffect is probably discarding/overriding user changes.

Try removing it. For example:

  useEffect(() => {
    localStorage.setItem('theme', theme);
  }, [theme]);
about 4 years ago · Santiago Trujillo Relatório

0

You've got a classic effect hook infinite loop here. The effect hook has a dependency on theme. If you call setTheme inside the hook, it will re-run ad infinitum.

I would recommend creating a theme context provider component like this. Since you're using Typescript, you should avoid any and properly type all your values.

import { createContext, useState, useEffect, FC } from "react";

type Theme = "light" | "dark";

interface ThemeContextValue {
  theme: Theme;
  toggleTheme: () => void;
}

export const ThemeContext = createContext<ThemeContextValue>({
  theme: "light",
  toggleTheme: () => {},
});

export const ThemeContextProvider: FC = ({ children }) => {
  // initialise state from localStorage
  const [theme, setTheme] = useState<Theme>(
    (localStorage.getItem("theme") ?? "light") as Theme
  );

  // update localStorage when the theme changes
  useEffect(() => {
    localStorage.setItem("theme", theme);
  }, [theme]);

  const toggleTheme = () => {
    setTheme((current) => (current === "light" ? "dark" : "light"));
  };

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
};
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda