Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

130
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!