James
James

Reputation: 337

React must call with setTimeout to update view correctly

I'm making modifications to this file https://github.com/davidguttman/react-pivot/blob/master/index.jsx#L84 to move the Dimensions component out to a parent component.

One strange thing i noticed is that i have to call setTimeout(this.updateRows, 0) instead of this.updateRows() for the views to update correctly.

Any idea why this is so? AFAIK, setTimeout(_,0) simply makes the function call asynchronous (i.e. allows concurrent execution for performance). Why would that help with rendering views correctly? I'm asking this question to avoid "Programming by Coincidence".

Upvotes: 1

Views: 238

Answers (2)

Austin Greco
Austin Greco

Reputation: 33544

This is because setState is asynchronous.

Since you are reading from this.state in the updateRows function, it won't work until the state is actually updated. Using setTimeout as you did, is one way to allow the state to update. setState will complete, and then updateRows will execute in the next frame.

A better way would be to use the callback parameter of setState

this.setState({dimensions: updatedDimensions}, () => {
  this.updateRows();
});

Another option is to keep any state changes in an object and pass it into the function instead of reading directly from this.state, but this can lead to much more complexity.

Upvotes: 1

Andy Gaskell
Andy Gaskell

Reputation: 31761

In this instance it's probably less about "concurrent execution" and more about the event loop. The setTimeout call removes function execution from the current call stack and adds an entry to the message queue. The currently executing stack will run to completion before the next message in the queue begins execution.

I don't know why this is required in this particular instance - some sort of state must be getting set in the current stack that's required for updateRows to produce the desired result.

Upvotes: 1

Related Questions