A simple way to deal with closure over a stale state in React code

varadan13

Aneesh

Posted on September 8, 2023

A simple way to deal with closure over a stale state in React code
 const [stateA, setStateA] = React.useState('A');

  React.useEffect(() => {
    setInterval(() => {
      if (stateA === 'A') {
        doSomething();
      } else {
        doSomethingElse();
      }
    }, [60000]);
  });
Enter fullscreen mode Exit fullscreen mode

In the above code stateA is a React state which can change based on user actions but the reference to stateA withint the callback of setInterval remains always set to the value "A" which is problematic.

Why does this happen? The setInterval callback captures the value of stateA when it is created, and it does not automatically update when stateA changes. This is known as a closure over a stale state.

We can tackle this issue by using a ref. Here is how.

  const [stateA, setStateA] = React.useState('A');

  const stateARef = React.useRef(null);
  stateARef.current = stateA;

  React.useEffect(() => {
    setInterval(() => {
      if (stateARef.current === 'A') {
        doSomething();
      } else {
        doSomethingElse();
      }
    }, [60000]);
  });
Enter fullscreen mode Exit fullscreen mode

What is happening here?

In this version, we create a stateARef using React.useRef(), and then immediately assign the current value of stateA to stateARef.current. By doing this, we ensure that stateARef.current always reflects the latest value of stateA, even within the setInterval callback.

πŸ’– πŸ’ͺ πŸ™… 🚩
varadan13
Aneesh

Posted on September 8, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related