I know its not remended to create add async to useEffect but how can I make sure my function is pletely done before continuing
Here is my code
useEffect(
() => {
const RetrieverDataProcess = async () => {
const GetMainListResults = await GetMainList(FORMSTATUS.ID);
setMAINOBJECT(GetMainListResults); //useState
console.log(2)
}
console.log(1);
RetrieverDataProcess();
console.log(99);
}, [])
If I run in my console its showing
1
99
2
I was hopeing its
1
2
99
I know its not remended to create add async to useEffect but how can I make sure my function is pletely done before continuing
Here is my code
useEffect(
() => {
const RetrieverDataProcess = async () => {
const GetMainListResults = await GetMainList(FORMSTATUS.ID);
setMAINOBJECT(GetMainListResults); //useState
console.log(2)
}
console.log(1);
RetrieverDataProcess();
console.log(99);
}, [])
If I run in my console its showing
1
99
2
I was hopeing its
1
2
99
Share Improve this question edited Nov 11, 2020 at 0:34 Matthias 15.4k9 gold badges48 silver badges64 bronze badges asked Nov 28, 2019 at 19:14 HawkHawk 5261 gold badge8 silver badges25 bronze badges 1- Possible duplicate of useState set method not reflecting change immediately – Emile Bergeron Commented Nov 28, 2019 at 20:07
4 Answers
Reset to default 4Are you doing this because you want the MAINOBJECT
state property to be set by the time you're ready to execute console.log(99)
?
If so, one thing you could do is use an additional useEffect
hook that only executes when the state property MAINOBJECT
updates:
useEffect(() => {
if (MAINOBJECT) {
console.log(99);
}
}, [MAINOBJECT]);
Can you try this (not at pc right now)
useEffect(
() => {
const RetrieverDataProcess = async () => {
const GetMainListResults = await GetMainList(FORMSTATUS.ID);
setMAINOBJECT(GetMainListResults); //useState
return console.log(2)
}
console.log(1);
RetrieverDataProcess().then(()=>{
console.log(99);
});
}, [])
You may use an Immediately Invoked Function Expression or IFFY. This will also allow you to use async/await instead of going back to then-chaining.
Essentially you are wrapping the effect body in an async function, which you immediately invoke.
useEffect(() => {
(async function anyName() {
const RetrieverDataProcess = async () => {
const GetMainListResults = await GetMainList(FORMSTATUS.ID);
setMAINOBJECT(GetMainListResults); //useState
console.log(2);
}
console.log(1);
// now you can await the async function to make sure it pletes
await RetrieverDataProcess();
console.log(99);
// note the invocation:
})();
}, [])
Just put your logic outside the EFFECT.
You can define an async function in ponent and then call it in EFFECT. If you care the performance, wrap it with useCallback
. Don't forget setting it as a dependency.
The better practice is to extract the static logic into small functions outside the ponent.