On the async nature of setState


(Vlad "Reign" Zelinschi) #1

Hello,

I’m writing a blog post on the async nature of setState method, also trying to understand this better. Quoting from the docs:

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.

There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

After stumbling over this post - http://www.bennadel.com/blog/2893-setstate-state-mutation-operation-may-be-synchronous-in-reactjs.htm and putting up together this example (https://github.com/r31gN/react-set-state-test - check index.html), I can conclude that when things run outside of React context, setState will trigger a sync update (calling render and everything immediately). This can be see in my example for setTimeout, AJAX call and addEventListener.

However, when things run inside React context, setState will trigger an async action (the onClick example - thus potentially creating issues with state if you refer to it immediately).

I’d like to know if my understanding of this is correct or I am missing something.

Also, after reading a bit through React source code, I understand that actually, setState is just a simple method. It’s not async. It just calls different updating strategies under the hood, and those may be sync or async, depending on wether React can batch updates or not for performance reasons (if things happen inside React context or not). It this true?

Thank you!


(Sophie Alpert) #2

I think everything you’ve written here sounds correct.


(Michel Weststrate) #3

I blogged about this subject recently, in the end. I just stopped using setState for local component state.


(Ben Junya) #4

I think you’re fighting the framework here… Don’t mean to be a downer, but this just doesn’t feel like the right way to do it. I can understand a larger scale project using stores and the flux pattern, but for simple components as a library for views? I don’t feel like it’s necessary. You’re adding more work (and complexity) by fighting the framework, when you can easily do what Ryan Florance was saying in that first comment on your article. It seems silly to fight the original intended use just for the sake of not understanding what React was meant to do in the first place.


(Michel Weststrate) #5

It is indeed definitely not necessary, but a very useful pattern if you have MobX in place anyway for your stores etc. Not sure what you are referring to with “for the sake of not understanding what React was meant to do in the first place”. It is perfectly clear to me why React optimizes rendering by doing rendering async. Just the choice to make state async as well seems suboptimal to me, it is generally more important that the state is in sync with your logic too avoid subtle bugs and confusion, then it is important that it is in sync with the DOM (there are other means to synchronize on that as well).


(Giorgim) #6

it is generally more important that the state is in sync with your logic too avoid subtle bugs and confusion

Well said.