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?
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 };
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.