score:10

Accepted answer

You can use a ref to keep track of the counter value independently

 const [counter, setCounter] = useState(0);
 const counterRef = useRef(counter)

Whenever you update counter you update counterRef as well:

const newCounter = counter + 1
setCounter(newCounter);
counterRef.current = newCounter

And then check it:

if (counterRef.current !== counter) {
   alert("counter was changed");
} else {
   setAsyncCounter(counter);
}

Codesandox

score:1

As @thedude mentioned, you will need to use the useRef hook – it was made exactly for your use case, as the docs say: "It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes."

I think you might just want to add a simple boolean:

  const counterChanged = useRef(false);

and then when you update the counter, you update this too.

            counterChanged.current = true;
            setCounter(counter + 1);

and inside your async function, you set it to false and then check if it's been changed.

counterChanged.current = false;
            await new Promise(resolve => {
              setTimeout(() => {
                resolve();
              }, 4000);
            });
            if (counterChanged.current) {
            // alert

score:1

I've found another answer by asking the question on facebook-rect github. Apparently, since setting a state is a function, it's first argument is the current state.

so it is possible to have access to the previous value by using this snippet when setting the counter value:

 setCounter(prevValue => {
          alert(prevValue + " " + counter);
          return counter + 1;
        });

https://github.com/facebook/react/issues/19270 https://reactjs.org/docs/hooks-reference.html#functional-updates


Related Query

More Query from same tag