There is a Profile component that creates a 3D face using an async function. To inform the user to wait, two dispatches is fired before and after the heavy task inside the UseEffect. The problem is both of these dispatched only fire after the heavy task is done.
Profile.js
const Profile = (props) => {
const [face3D, setFace3D] = useState(null)
const { state, dispatch } = useContext(UserContext)
const drawFace = async () => {
// a heavy calculation
}
useEffect(() => {
// show user loading
dispatch({
type: "USER_LOADING",
payload: true
})
drawFace().then( face => {
setFace3D(face)
// clear user loading
dispatch({
type: "USER_LOADING",
payload: false
})
})
}, [props.data])
return (
<Canvas>
{ face3D }
</Canvas>
)
}
export default Profile
UserContext.js
import React, { createContext, useReducer } from 'react'
import { createReducer } from 'react-use'
import logger from 'redux-logger'
import thunk from 'redux-thunk'
export const UserContext = createContext()
const useThunkReducer = createReducer(thunk, logger);
const UserContextProvider = (props) => {
const initialState = {
loading: false
}
const [state, dispatch] = useThunkReducer(UserReducer, initialState)
return (
<UserContext.Provider value={{ state, dispatch }}>
{ props.children }
</UserContext.Provider>
)
}
export default UserContextProvider
PS: redux-logger shows a correct sequence of dispatching, even logging the reducer shows changing the state to true and finally to false but the state only reflects the last dispatch (a situation similar to mutating the state, but it is not mutated)