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

98
Views
Hook useState with useEffect

I encountered this behavior. Two onChange are called in turn. One of them saves data to the state, and use the previus state to generate new one.

const onChange = (data) => {
    setState1((prev) => {
      console.log("onChange set state");
      return [...prev, data];
    });
  };

The other just prints something to the console.

const onChange2 = (data) => {
    console.log("onChange2");
  };

onChange and onChange2 called after click on button

<button
        onClick={() => {
          onChange({ foo: "bar" });
          onChange2();
        }}
      >
        2
      </button>

useEffect - saves data to state

const [state, setState] = useState(0);
  const [state1, setState1] = useState([]);

  useEffect(() => {
    setState((prev) => {
      console.log("use effect set state");
      return prev + 1;
    });
  }, []);

So, if you do not use useEffect (comment out), the console log, which in the first onChange will be called first, then the console log from the second onChange

enter image description here

enter image description here

If you uncomment useEffect, then the console will log from onChange2 first, then from onChange

enter image description here

enter image description here

Why is this happening, who can tell?

CodeSandBox: https://codesandbox.io/s/eager-hooks-sczvb

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

0

The call order of onChange and onChange2 appear to change because the console.log in onChange is inside the callback passed to setState1.

If you move the console.log directly in the onChange you will see that the order is the same with or without useEffect.

const onChange = (data) => {
  console.log("onChange set state");
  setState1((prev) => {
    return [...prev, data];
  });
};

It's important to understand that when you call setState there is no guarantee that the state will be changed immediately, it's up to React to decide when to apply the new state and trigger a new render.

This is why the callback passed to setState should only return a new state and not run any effects (such as console.log) since the moment this code is run is considered in implementation detail and could change with any version of React.

about 4 years ago · Juan Pablo Isaza Report

0

Expected behavior is onChange2 called first, and onChange set state called second whatever useEffect body is commented. because onChange2 called right now. but onChange set state in setState fn called after rendered。

The "bug" looked is why onChange set state called first when first click. Hmm... find react computeExpirationForFiber. setState callback execute sync or async by different conditions. It's hard to read.

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!