How React.js works under the hood?

Before diving deeper into React first, we’ll see the React actually is. According to official React docs;

React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”.

Some of you might be wondering what the heck is this declarative means, It means React uses the Declarative Programming paradigm — means defining what to be done or how UI should look like, without mentioning how it needs to be done.

Declarative views make our code more predictable and easier to debug.

The Components are Independent and reusable bits of code. Everything we see on the website can be dived into components, for example, React.org reacts official website is also built with react

Here all the things can be divided into smaller components like the navbar is a component, the header, and the cards describing React can be examples of using reusable components as they all have the same UI only the content is different, you got the point.

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).

source: https://codeaccepted.wordpress.com/2014/04/08/depth-and-breadth-first-search/

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

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

2. The developer can hint at which child elements may be stable across different renders with a key prop.

This means while creating child components adding the key will help React to track changes on the child component. 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. For example,

<ul>
<li>Duke</li>
<li>Villanova</li>
</ul>
// just adding Connecticut on the top<ul>
<li>Connecticut</li>
<li>Duke</li>
<li>Villanova</li>
</ul>

here we’ve added another child to <ul> on top of all while recursing React will mutate every child instead of realizing the last two components are the same. This might lead to slow down the reconciliation process.

So what's the solution for this then? In order to solve this kind of problem, React uses the key attribute. By using the key attribute, React will use this key to match children in the original tree with children in the subsequent tree, by using the same above example with keys,

<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
// adding Connecticut with key 2014 on top<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>

Just by adding a key attribute, React knows that the element with key '2014' is the new one, and the elements with the keys '2015' and '2016' have just moved.

How React updates the browser DOM?

Once React creates the new virtual DOM and compare it with the old one, it creates a list of minimal possible changes to the browser DOM.

Once it completes its list, it will fire off all the changes, one after the other, in a single continuous cycle without any reflow.

Reflow is the web browser process for re-calculating the positions and geometries and color of elements in the document, for the purpose of re-rendering part or all of the document.

Conclusion

Brief summary of how React updates and differentiates the new changes to be reflected on the browser DOM, and how the element is rendered on the DOM.

Basically, React uses the createElement() to convert the JSX to the React Element, and on every setState or dispatch, it recreates the virtual DOM and compare it using Diffing Algorithm, and then renders the element in the DOM using the render method from the react-dom library.

Reference:

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store