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

135
Visualizações
Unsure if I'm using setState correctly because my state is not updated during initial load

I have a state that stores the current app's theme either dark or light. I use useEffect hook to store the state changes in localStorage so that when the user refreshes the page, their preferred theme will get saved and another useEffect hook to update my state during the initial load. However, my state does not update during that initial load.

Things I've tried:

  1. Make sure the useEffect during initial load is placed before the useEffect to store the theme state
  2. Use Promise to make sure that my changeTheme function is only triggered after the state has changed on load
  3. I logged my results so I know that localStorage did not have any problems with saving my states or keeping track the changes, but the setState function inside my first useEffect hook was the one that did not update my state properly.

Below are my codes:

  const [theme, setTheme] = useState({});

  useEffect(() => {
    const loadedTheme = JSON.parse(localStorage.getItem(themeStorage))
    if (loadedTheme) {
      console.log("Initial load")
      console.log(loadedTheme);
      console.log("Setting theme to localStorage")
      Promise.resolve()
        .then(() => { setTheme({ dark: loadedTheme.dark }) })
        .then(() => { console.log(theme) })
        .then(() => changeTheme())
    }
  }, [])

  useEffect(() => {
    localStorage.setItem(themeStorage, JSON.stringify(theme))
    console.log("Inside useEffect to save changed theme")
    console.log(theme)
  }, [theme])

  function changeTheme() {
    console.log("Inside changeTheme function");
    console.log(theme);
    if (!theme || !theme.dark) { //light turns to dark
      for (let vars of Object.keys(varTheme)) {
        document.documentElement.style.setProperty(`--${vars}`, varTheme[vars][0]);
      }
      setTheme({ ...theme, dark: true })
    }
    else {
      for (let vars of Object.keys(varTheme)) { //dark turns to light
        document.documentElement.style.setProperty(`--${vars}`, varTheme[vars][1]);
      }
      setTheme({ ...theme, dark: false })
    }
  }
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

It's a bit unclear what you think the issue is, but I suspect that you are seeing/describing theme not updating in the first useEffect hook.

Issue

The reason for this is that React state is considered const and immutable. Within the useEffect callback the theme state value is closed over in callback scope and no matter of waiting or Promise chaining will change the state value closed over in scope.

const [theme, setTheme] = useState({}); // <-- initial state

useEffect(() => {
  const loadedTheme = JSON.parse(localStorage.getItem(themeStorage))
  if (loadedTheme) {
    console.log("Initial load")
    console.log(loadedTheme);
    console.log("Setting theme to localStorage")
    Promise.resolve()
      .then(() => { setTheme({ dark: loadedTheme.dark }) })
      .then(() => { console.log(theme) }) // <-- still initial state
      .then(() => changeTheme())
  }
}, []); // <-- mounting "instance" of state

You then invoke changeTheme which from the enclosure and it will also sill access the "stale" state of the enclosure.

Solution

LocalStorage is synchronous, so you can set your initial state from it with an initializer function.

const loadThemeFromStorage = () => {
  const { dark } = JSON.parse(localStorage.getItem(themeStorage)) ?? {};
  return { dark };
};

const [theme, setTheme] = useState(loadThemeFromStorage());

Now with the state already initially set you can safely call changeTheme in the mounting useEffect hook.

useEffect(() => {
  console.log("Initial load");
  console.log(theme);
  changeTheme();
}, []);

useEffect(() => {
  localStorage.setItem(themeStorage, JSON.stringify(theme));
  console.log("Inside useEffect to save changed theme");
  console.log(theme);
}, [theme]);
about 4 years ago · Juan Pablo Isaza 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