Issuing an AJAX request in the setState () callback

I encoded my ReactJS AJAX requests as follows:

this.setState({ isLoading: true, results: null }); $.get(ajaxUrl, function(results) { this.setState({ isLoading: false, results: results }); }.bind(this)); 

This is just an example, it does not have error handling, throttling, query cancellation, etc. But the point is this. I basically ask to set some state and then execute the request.

Looking at some other code on GitHub, I noticed that some people write their AJAX calls in the setState callback:

 this.setState({ isLoading: true, results: null }, function() { $.get(ajaxUrl, function(results) { this.setState({ isLoading: false, results: results }); }.bind(this)); }.bind(this)); 

Is there a good reason for this? The docs say :

There is no guarantee that setState calls will work synchronously, and calls can be collected to improve performance.

Thus, there is no guarantee that setState changes state before returning, but I see no mention of the fact that various setStates may not perform properly. So the worst thing that can happen is that the loading state is not working. Is this what the latest style is trying to solve? Is there any other risk that I do not see?

+5
source share
1 answer

but I don’t see any mention that various setState may perform out of order

That's right, they start in order, and from a UX point of view, you don’t want to show the load indicator in less than half a second.

The case for this looks something like this:

 this.setState({ isLoading: true, results: this.state.results || [] }, function() { $.get(ajaxUrl, function(results) { this.setState({ isLoading: false, // note! we're referring to state here results: this.state.results.concat(results) }); }.bind(this)); }.bind(this)); 

However, this can also be resolved by passing a setState callback instead of an object. Thus, we can see the status after previous updates in the queue have occurred.

It is also possible to transfer a function with a signature function (status, props). This can be useful in some cases when you want to assign an atomic update that refers to the previous status + props value before setting any values.
- Component Api Docs

 this.setState({ isLoading: true, results: null }); $.get(ajaxUrl, function(results) { this.setState(function(state){ return { isLoading: false, results: state.results.concat(results) }; }); }.bind(this)); 

For best results, abstract it all into a high-level component or mixin. You do not want to deal with this logic in every component that retrieves data.

+3
source

All Articles