Home > Blockchain >  Understanding Code Flow For Setting State in React
Understanding Code Flow For Setting State in React

Time:01-04

I have this basic code which updates a state from a handler:

const wait = (ms) => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};

export default function App() {
  async function handleClick() {
    setData(1);
    console.log("first click");
    console.log(data);
    await wait(1000);
    setData(2);
    console.log("second click");
    console.log(data);
  }

  const [data, setData] = React.useState(0);
  return (
    <div>
      {data}&nbsp;
      <button onClick={() => handleClick(setData)}>Click Me</button>
    </div>
  );
}

I am trying to understanding the order of operations, could someone please verify or point me in the right direction of what is happening? I have researched around but haven't found conclusive sources on what I think is happening.

  1. we click the button, triggering the handler
  2. the handler runs setData(1), enqueuing a task to the event loop
  3. console.log('first click') runs
  4. we log the state (data), which is still 0, as the setter has only been enqueued
  5. we run into the wait function, so we exit out to the synchronous code flow as we wait for the 1000ms
  6. the sync code finishes running, so we dequeue the next task, which is the setter function, the state is now set to 1, and the view re-renders and reflects that new state
  7. after 1 second has elapsed, we return to the code after wait function
  8. setData(2) enqueues another task
  9. 'second click' is logged
  10. 0 is stil logged, as our local state has not changed
  11. the sync code finishes, we dequeue the setter, re-rendering the view, causing 2 to show up

Is this all correct? Have I misunderstood anything? Thanks for any help.

CodePudding user response:

Yes, you've got this down correctly, except possibly for the bit

runs setData(1), enqueuing a task to the event loop

This may or may not involve the event loop. What happens in setData is specific to react.js, and won't necessarily enqueue a task in the browser event loop. It certainly does "somehow" schedule the state update and re-rendering of the component - within react.

If I remember correctly, react.js does schedule the render caused by setData(1) for the end of the native click handler, i.e. when the call to your onClick handler returns to react code. And for setData(2), the rendering might actually happen synchronously within the setData call, as react does not control the context. This is however subject to change (the devs are talking about batching multiple updates together asynchronously) and should be considered an implementation detail. If you're curious, just place a console.log in the render function of your component, but do not write any code that relies on the order observed in this test!

  • Related