When diffing two trees, React first compares the two root elements.
The behavior is different depending on the types of the root elements.
Elements Of Different Types
//this will destroy the old Counter and remount a new one
Whenever the root elements have different types, React will tear down the old tree and build the new tree from scratch. When tearing down a tree, old DOM nodes are destroyed. Component instances receive componentWillUnmount(). When building up a new tree, new DOM nodes are inserted into the DOM. Component instances receive componentWillMount() and then componentDidMount(). Any state associated with the old tree is lost.
DOM Elements Of The Same Type
//by comparing these two elements, React knows to only modify the
//className on the underlying DOM node
<div className="before" title="stuff" />
<div className="after" title="stuff" />
When comparing two React DOM elements of the same type, React looks at the attributes of both, keeps the same underlying DOM node, and only updates the changed attributes.
Component Elements Of The Same Type
When a component updates, the instance stays the same, so that state is maintained across renders.
React updates the props of the underlying component instance to match the new element, and calls componentWillReceiveProps() and componentWillUpdate() on the underlying instance.
Next, the render() method is called and the diff algorithm recurses on the previous result and the new result.
Recursing On Children
//React will match the two <li>first</li> trees, match the two <li>second</li> trees,
//and then insert the <li>third</li> tree.
By default, when recursing on the children of a DOM node, React just iterates over both lists of children at the same time and generates a mutation whenever there’s a difference.
//now React knows that the element with key '2014' is the new one,
//and the elements with the keys '2015' and '2016' have just moved.
When children have keys, React uses the key to match children in the original tree with children in the subsequent tree.