Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

238
Views
Why is React state not updated inside functions?

I have a component that renders a table with objects. This component shows a button that, when pressed, sends the parent a specific object. The parent must set it in the state to display some graphical stuff. The rendering is working correctly, what I don't understand is why I am getting an outdated value after setting the state correctly. It's not a race condition, React is simply ignoring the updated value of a variable, even when it re-renders the component correctly.

A minimal example:

import { useState } from "react";
import { SomeComponent } from "./SomeComponent";

export default function App() {
  const [currentID, setCurrentID] = useState(null);

  function getData() {
    console.log("Getting data of: ", currentID); // PROBLEM: this is null
  }

  function setAndRetrieveData(value) {
    setCurrentID(value);

    // Just to show the problem and discard race conditions.
    setTimeout(() => {
      getData();
    }, 1500);
  }

  return (
    <div className="App">
      <h1>Current ID: {currentID}</h1> {/* This works fine */}
      <SomeComponent getInfoFor={setAndRetrieveData} />
    </div>
  );
}

SomeComponent:

export function SomeComponent(props) {
  const randomID = 45;

  return <button onClick={() => props.getInfoFor(randomID)}>Get info</button>;
}

Edit react update state

Even with solutions like useStateCallback the problem persists.

Is there a way to do this without having to use the awful useEffect which is not clear when reading the code? Because the logic of the system is "when this button is pressed, make a request to obtain the information", using the hook useEffect the logic becomes "when the value of currentID changes make a request", if at some point I want to change the state of that variable and perform another action that is not to obtain the data from the server then I will be in trouble.

Thanks in advance

about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

I think this is an issue with the way Javascript closures work.

When you execute a function, it gets bundled with all the data that pertains to it and then gets executed.

The issue is that you call this:

setTimeout(() => {
      getData();
    }, 1500);

inside setAndRetrieveData(value).

Even though it's inside a setTimeout, the getData() function has been bundled with the information it needs (currentID) at that point in time, not when it actually runs. So it gets bundled with the currentId before the state update takes place

Unfortunately, I would recommend using useEffect. This is the best way to ensure you avoid issues like this and any potential race conditions. Hopefully someone else can provide a different approach!

about 4 years ago · Juan Pablo Isaza Report

0

when setAndRetrieveData is called it sets a state that leads to the component being rerendered to reflect the new state. When the timeout finishes The function getData was created in the previous render. And thus only has access to the state variable from the previous render. That now is undefined.

what you could try is using a useEffect hook that that listens to changes of currentID.

   useEffect(() => {
      const timeoutId = setTimeout(() => {
         // Do something with the updated value
      },1000);
      return () => {
          // if the data updates prematurely 
          // we cancel the timeout and start a new one
          clearTimeout(timeoutId);
      }
   },[currentID])
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!