Reconciliation
Introduction
React's Render function returns a tree of React elements as state or props change. But render can return a different tree of elements. React needs to figure out how to update the tree in the most efficient way.
React's algorithm for working out the tree diffs is O(n), and it assumes only two things; Elements created of different types will produce a new tree; Developers can "hint" at which elements are stable across renders using the "key" property on things like lists.
The O(n) algorithm implemented by React first compares the two root elements. The behaviour is different depending on if these elements are of the same type, or not.
Elements of different types
If the elements are different, for example rendering an img to div, React will tear down the tree and build up the new one from nothing. While React tears down a root, it also destroys the children too; including their state. For example the only difference below for the parent count display is, one is rendered with a div, and the other span; two seperate components of course, clicking the toggle will tear down the childs state.
Child Component Count: 0
Elements of the same type
If the elements are the same, when React compares them, React will adjust the attributes and keep the same DOM node. For example changing className or required on an input field; the node itself will remain with its state. For example below, the only thing which changes when we toggle between these components is the className, which means the DOM nodes themselves aren't affected and children aren't torn down nor is the root. The state is unaffected.
Child Component Count: 0
Recursion
Adding to lists is one cool example of how React works, adding to the bottom works great because it sees there is a difference in one of the last DOM nodes; and makes a quick addition.
- One
- Two
The problem is though, in React, if you add to the front, or the middle, React can work overtime because it doesn't realize it can keep the two of the elements, and it will mutate every child of the unordered list. This can be solved with lists and mapped things though, with the "key" attribute, which is why you always see it in console when it isn't included. This is because it helps React track which nodes need updating and which don't from the original tree. React knows which element is the new addiction if this were the case.
- One
- Two