Asynchronous function keeps reading old value of global variab;e

While writing a React app, I run in a problem that can be simplified like this:

    const [prjToFetch, setPrjToFetch] = React.useState([]);

    React.useEffect(() => {
    console.log("Before " + prjToFetch)
    async function func(){
      let myPromise = await new Promise(function(myResolve, myReject) {
        setTimeout(function() { myResolve("I love You !!"); }, 3000);
      });

      
      console.log("After: " + prjToFetch)
      return myPromise;
    }

    func()
  }, [prjToFetch])

I have a button that pushes the value "a" into the array prjFetch whenever it is pressed:

const handleClick = () => {
  setPrjToFetch([...prjToFetch, "a"]);
}

If I press the button once, the output of the previous code is:

Before a
(3 seconds of idle time)
After a

This is exactly what I expect. But let’s suppose I press the button twice in a row, then the output is:

Before a
Before a a
(3 second of idle time)
After a
After a a

Why is the first "After" returning only "a" and not "a a"?

Notice that I also tried to rewrite the code as:

  React.useEffect(() => {
    console.log("Before " + prjToFetch)
    async function func(){
      await new Promise(function(myResolve, myReject) {
        setTimeout(function() { myResolve("I love You !!"); }, 3000);
      });
    }

    func().then(() => {
      console.log("After: " + prjToFetch)
    })
  }, [prjToFetch])

But the result is the same

8 thoughts on “Asynchronous function keeps reading old value of global variab;e”

Leave a Comment