Using value of state variables right after updating in React.js

Amit Merchant · March 10, 2022 ·

Working on one of the apps which built on top of React.js, I stumbled upon a scenario where I needed to use the value of a state variable immediately after it’s updated.

The problem

Let me demonstrate this using the following example.

import React, { useState } from 'react';

function CustomerPage() {
  const [allowNext, setAllowNext] = useState(false);

  function moveNextPage() {
      if (allowNext) {
        // logic to move the user
        // to the next page
      }
  }  

  return (
    <div>
      <p>Customer Page</p>
      <button>
        Next
      </button>
    </div>
  );
}

As you can tell, there’s a component called <CustomerPage> and in here, we’re defining a state variable called allowNext which can be updated by the setAllowNext() function using the useState hook.

The initial value of this state variable is set to false.

Now, what we want is when the user clicks on the Next button, the value of the allowNext should be set to true and then call the moveNextPage() function. And in that function, we need to check whether the value of allowNext is true to allow the user to move to the next page.

The wasted solution

Initially, this is what I did to solve this.

import React, { useState } from 'react';

function CustomerPage() {
  const [allowNext, setAllowNext] = useState(false);

  function moveNextPage() {
      if (allowNext) {
        // logic to move the user
        // to the next page
      }
  }  

  return (
    <div>
      <p>Customer Page</p>
      <button onClick={() => {
          setAllowNext(true);
          moveNextPage();
      }}>
        Next
      </button>
    </div>
  );
}

As you can tell, I set the value of allowNext to true using setAllowNext and immediately called moveNextPage(). I was under impression that the value of allowNext would be true when calling moveNextPage().

But I was wrong. The value of allowNext was still false since useState’s setters doesn’t set value of state variables synchronously. So, setAllowNext doesn’t actually update the value of allowNext immediately and hence we don’t get the desired result.

The actual solution

To get around this issue, we need to couple the other React hook called useEffect and set the allowNext as its dependency. So, once the value of allowNext is updated, the useEffect gets triggered and this is where we can call the moveNextPage() function.

Here’s what this will look like when putting it altogether.

import React, { useState, useEffect } from 'react';

function CustomerPage() {
  const [allowNext, setAllowNext] = useState(false);

  useEffect(() => {
    moveNextPage()
  }, [allowNext])

  function moveNextPage() {
      if (allowNext) {
        // logic to move the user
        // to the next page
      }
  }  

  return (
    <div>
      <p>Customer Page</p>
      <button onClick={() => setAllowNext(true)}>
        Next
      </button>
    </div>
  );
}

As you can tell, now when the value of allowNext is set to true, the useEffect will be triggered. This will call the moveNextPage() function and the value of allowNext will be true there as well just like how we expected!

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?