How React.js works under the hood?
By: Vinay Dagar
Tags: Reactjs, Reconciliation, React, Diffing Algorithm, React Under The Hood

While declaring the React component, you’ll notice that React components return some HTML

What happens to this HTML Code?

This syntax, using HTML inside JavaScript is called JSX i.e., JavaScript XML. It is a recommended way of describing how our UI should look like. React embraces the fact that rendering logic is inherently coupled with other UI logic: how events are handled, how the state changes over time, and how the data is prepared for display.

Now what happens is, the babel compiles down our JSX syntax, which we write in our components to create elements, to React.createElement() call. In simple words, JSX elements are just the syntactic sugar for calling createElement().

What is this createElement()?

The createElement function creates and returns a new React element. An element describes what we want to see on the screen.

React.createElement(

type,

[props],

[...children]

)

It means that the following statement,

export default (props) => {

return <div className="container">Hello There!</div>

}

is identical with the following,

export default (props) => {

return React.createElement('div',

{className: "container"}, "Hello There");

}

How these elements are rendered to browser DOM?

React uses the concept of Virtual DOM, which is nothing but the exact same copy of the browser DOM, but a lot faster than the browser DOM.

Browser DOM & Virtual DOM comparison

Till now we’ve seen what happens to our JSX element which we create in our React component. But now you might be wondering what happens to those elements that have been mutated by createElement or How these elements will be rendered to the browser DOM?

What Reacts basically does with Virtual DOM is compare it with browser DOM and modifies the browser DOM. We will dive deeper oh How it compares what triggers React to make it compare a bit later.

To render the elements to the browser DOM react uses another library to make it happen called “react-dom”. According to official docs, The react-dom package provides DOM specific methods. These methods could be render(), hydrate(), findDOMNode(), createPortal(), unmountComponentAtNode(). Right now we are only interested in the render() function.

ReactDOM.render(element, container[, callback])

The render method from the react-dom package simply renders the React element, which is created by the createElement() function, into the DOM under the supplied container and returns a reference to the component.

And if the element has already been rendered in the container, then it will just update the DOM as necessary to reflect changes. The render does not modify the container node.

In the following code, the App component will be rendered under the container with the id app.

Here we can see, the elements below the div with id app is actually the content rendered by React.

Now we’ve seen how the elements are rendered on the DOM in the first place, but How React nows when to re-render or update the DOM?

Reconciliation

So whenever, the state or props get changed or dispatch is called, React knows as it is observing everything, and basically recreates the entire virtual DOM from scratch, and list down the minimal changes possible, and compare the newly created virtual DOM with the actual browser DOM,

The process which compares and updates the changes on the screen is called reconciliation. React uses the Diffing Algorithm for the comparison of both browser DOM and virtual DOM.

React implements a heuristic O(n) algorithm based on two assumptions:

1. Two elements of different types will produce different trees.

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. React parses the tree by using Breadth-first-search(BFS).

Any components below the root will also get unmounted and have their state destroyed. For example,

<div>

<Counter />

</div>

// changing div to span

<span>

<Counter />

</span>

changing the div the parent tag of <Counter/.> will also destroy the <Counter/> and lead to recreating both the parent/root span and Counter component.

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" />