I know its not recommended to create add async to useEffect but how can I make sure my function is completely 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
The useLayoutEffect function is triggered synchronously before the DOM mutations are painted. However, the useEffect function is called after the DOM mutations are painted. I chose this example to make sure the browser actually has some changes to paint when the button is clicked, hence the animation.
React useState hook is asynchronous!
Anti-Pattern: async function directly in the useEffect React can run this async function but can not run the cleanup function. Don't use raw async function directly in the useEffect. useEffect(async () => { console. log('Hi :)') return () => { console.info('Bye!
TL;DR: useState is an asynchronous hook and it doesn't change the state immediately, it has to wait for the component to re-render. useRef is a synchronous hook that updates the state immediately and persists its value through the component's lifecycle, but it doesn't trigger a re-render.
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);
});
}, [])
Are 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]);
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 completes
await RetrieverDataProcess();
console.log(99);
// note the invocation:
})();
}, [])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With