简体   繁体   中英

How to make code synchronous in useEffect

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

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:
     })();
}, [])

Just put your logic outside the EFFECT.

You can define an async function in component 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 component.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM