#Some notes / further details based on the excellent article React’s diff algorithm
Assuming that react has batched multiple setState() calls that come from different component nodes (batched, because all calls happend before the js event loop ended), all of the given statements below are TRUE:
-
If multiple setState() calls are batched, react always looks first at the topmost dirty component and starts rendering from there.
-
React renders a tree of components until all dirty components have run/been touched exactly once. Rendering a complete tree (means: no early skips, shouldComponentUpdate() returns always true) from a common root component achieves this in a single run, because all dirty components can be touched.
This means, that each component's inner state represents its visual appearance; they are all "up-to-date". In this case React basically only resolves ONE of the batched setState() calls (the one from the topmost component) - there simply is no need for additonal subtree rendering because it would have the same outcome. -
If the render process on a root component is skipped early due to a shouldComponentUpdate() that evaluates to "false", all of the remaining, dirty/not reached child components are the beginning of a new subtree rendering - so although rendering is skipped early at the root, dirty child components will always get their latest state rendered.
React never ignores components for which setState() has been called - hence it does not matter, if a resolved setState() call from a different component further up in the tree skips its own rendering. -
If two unreleated components (means: mounted on two different branches in the tree, no common ancestor that is dirty) have setState() called (calls that are batched up by react), each of the two components are the start of a new subtree rendering.
Because none is the parent of the other, react has to start the render process two times in isolation because of their position in the tree (means: it starts a new subtree rendering for each of them). -
The only way a react component can get "out-of-sync" (means: appearance of component is not represented by its state) is when shouldComponententUpdate() is implemented insufficiently and therefore returns "false" although props/states differ (this can happen by ignoring certain nextProps/nextState parameters).
Recap: for child components with dirty state, statement 3 from above applies - they get their own render function called separately; thus they are neither lost nor ignored and therefore remain up-to-date regaring their appearance.