Reconciliation - jellyfish-tom/TIL GitHub Wiki

[SOURCES]

Once the virtual DOM has updated, then React compares the virtual DOM with a virtual DOM snapshot that was taken right before the update.

In summary, here's what happens when you try to update the DOM in React:

  1. The entire virtual DOM gets updated.
  2. The virtual DOM gets compared to what it looked like before you updated it. React figures out which objects have changed.
  3. The changed objects, and the changed objects only, get updated on the real DOM.
  4. Changes on the real DOM cause the screen to change.

How React “diffing” (Reconciliation) algorithm works:

  1. When diffing two trees, React first compares the two root elements. Than reconciliation alg. goes deeper into tree.
  2. When it meets element/node of different type (ex. instead of
    ), React will tear down the old tree and build the new tree from scratch. Full rebuild. 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.
  3. When element/node is of same type, than React looks at the attributes/properties of both, keeps the same underlying DOM node, and only updates the changed attributes.
  4. Keys

    React supports a key attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree. For example, adding a key to our inefficient example above can make the tree conversion efficient:

    Second take

    a) different elementy type When react diffs elements, whenever type changes, whole element and its subtree will get rerendered.

    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.

    b) same element 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.

    c) same dom node type

    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. For example:

    <div className="before" title="stuff" />
    
    <div className="after" title="stuff" />
    

    By comparing these two elements, React knows to only modify the className on the underlying DOM node.

    Keys

    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.

    React supports a key attribute. When children have keys, React uses the key to match children in the original tree with children in the subsequent tree.

    Key should be unique among siblings, not globally. Usually some data that already has unique ID gets rendered. If not you can ex. hash part of content to get a key.

    As a last resort, you can pass an item’s index in the array as a key. This can work well if the items are never reordered, but reorders will be slow.

    Reorders can also cause issues with component state when indexes are used as keys. Component instances are updated and reused based on their key. If the key is an index, moving an item changes it. As a result, component state for things like uncontrolled inputs can get mixed up and updated in unexpected ways.

⚠️ **GitHub.com Fallback** ⚠️