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

138
Visualizações
The useReducer is not updating the state value

Hiho!

I thought it would be cool for my page to have a 100% covering black transparent overlay with text when its waiting for data from the server. So it its waiting for data a 30% black overlay with the text "Loading ...". I wrote the context and provider and while it works it is a bit too fast :-). I want it to hide the overlay with a delay for 1500s (or less), so I tried changing the useState to a useReducer and implement the logic in setDisplayStateFunc:

import { createContext, useReducer, useState } from "react";

function useOverlay(display) {

    async function setDisplayStateFunc(state, action) {

        await new Promise(resolve => setTimeout(resolve, 1500));
        console.log(`returning: ${action}`);
        return action;
    }

    const [displayState, setDisplayState] 
        //= useState(display);
        = useReducer(setDisplayStateFunc, display);

    return { displayState, setDisplayState }
}

const OverlayContext = createContext();

function LoaderOverlay({ children, display = 'block' }) {

    const { displayState, setDisplayState } = useOverlay(display);

    return (
        <OverlayContext.Provider value={{ displayState, setDisplayState }}>
            <div className="loader" style={{ "display": displayState }}>
                <span>Loading ...</span>
            </div>

            {children}
        </OverlayContext.Provider>
    )
}

export { LoaderOverlay, OverlayContext };

The console.log I have there is outputting the right values, and out and about in my componets i use it by setting up useContext and then setDisplayState('none') after I'm done loading.

It works with useState, but I want a small delay. Where did I go wrong?

about 4 years ago · Santiago Gelvez
1 Respostas
Responde à pergunta

0

I don't think useReducer support async function. The notion of side effect should generally not be inside the reducer.

I would suggest using a useEffect to handle this inside of LoaderOverlay

import { createContext, useReducer, useState } from "react";

function useOverlay(display) {

    async function setDisplayStateFunc(state, action) {
        return action;
    }

    const [displayState, setDisplayState]
        = useReducer(setDisplayStateFunc, display);

    return { displayState, setDisplayState }
}

const OverlayContext = createContext();

function LoaderOverlay({ children, display = 'block' }) {

    const { displayState, setDisplayState } = useOverlay();

    useEffect(() => {
    async function waitSomeTime() {
      await new Promise(resolve => setTimeout(resolve, 1500));
      setDisplayState()
    }
    waitSomeTime()
    }, [setDisplayState])

    return (
        <OverlayContext.Provider value={{ displayState, setDisplayState }}>
            <div className="loader" style={{ "display": displayState }}>
                <span>Loading ...</span>
            </div>

            {children}
        </OverlayContext.Provider>
    )
}

export { LoaderOverlay, OverlayContext };

about 4 years ago · Santiago Gelvez 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