DEV Community

Cover image for The basics of React internals - Blog 1
thepurplecoder
thepurplecoder

Posted on • Edited on

The basics of React internals - Blog 1

React is one of the most popular javascript libraries for building user interfaces. The main advantage of react is when an update happens it only updates the DOM elements that need to be updated. It achieves this by using virtual DOM which is nothing but an internal representation of our UI.

Let’s try to understand how react manages virtual dom and how it evolves the virtual dom structure to support concurrent version.

For those of you who just want to get a gist of react internals I highly recommend to watch Lin Clark 's video of react fiber.

Let's start with the basics.

JSX

React introduces JSX for better developer experience. JSX is a syntactic sugar for React.createElement(type, props,...children) or _jsx/ _jsxs

For example when we define a component like this

In

the babel compiler transpiles the above code to

Out - React classic

And in current versions *_jsx will be there instead of React.createElement. Both performs the same. _jsx was created for improving our React development experience.*

React.createElement returns a JS object describing the node and its properties.
Eg:

const profile = <h1 className='welcome'>Hello World </h1>
Enter fullscreen mode Exit fullscreen mode

would return something like this

{
  type: 'h1',
  props: {
     className: 'welcome',
     children: ['Hello World']
  },
  ref: null,
  key: null,
  $$typeof: Symbol(react.element)
}
Enter fullscreen mode Exit fullscreen mode

The returned element has the following properties.

  • type
    The type of the element
    If it is a custom react element the type would be the reference of the function/class of the element.
    If it is a host element(like div in DOM) the type would be a string one

  • props
    The props of the element like its children or colour etc.,

  • $$typeof
    This key is just to ensure the component is created from react to prevent XSS. Dan Abramov has explained the importance of key in this article. Do check that out.

  • key
    It is used to uniquely identify the element in case the type of the element is not enough to identify it uniquely.

  • ref
    Reference of the instance if it is a custom react element or the dom node reference if it is a host element

Using this object builds a tree-like data structure i.e virtual DOM and stores it in memory.

Reconciliation

When an update occurs react uses the previously constructed virtual dom and generates a new tree based on the update. React compares these two versions and updates the elements in the DOM efficiently. This process is called Reconciliation

But if react actually compares every node/object in the tree with its previous version, it'd be time-consuming right?. To avoid this react uses a heuristic algorithm that is based on the following rules.

Elements of different types will generate different branches and subtrees

Eg:

<div> Hi I am a div </div>
Enter fullscreen mode Exit fullscreen mode

If the above element changes to the following element,

<span> Hi I am a span </span>
Enter fullscreen mode Exit fullscreen mode

Then react will delete the div and appends span into its parent. Similarly, if

<Hello/>

/* Changes to */

<Bye/>

Enter fullscreen mode Exit fullscreen mode

Then react will unmount Hello element or its instance and mounts Bye

Elements of the same type

If the type of both the elements is the same it will check whether the props changed. If it is changed it will then modify the props of the element. Simple!

Eg:

<Message text='Hi'/> ==> <Message text='Bye'/>
Enter fullscreen mode Exit fullscreen mode

will modify the text property from 'Hi' to 'Bye' in the Message instance.

<div className='active'/> ==> <div className='inactive'/>
Enter fullscreen mode Exit fullscreen mode

will modify the class of the div element

Elements of the same type but with different properties

Let's say we want to list a bunch of fruits like the following

<ul>
  <li>Banana 🍌</li>
  <li>Cherry πŸ’</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

And due to an update, we append an entry to the first child of ul element now our component will look like this.

<ul>
  <li>Apple 🍎 </li>
  <li>Banana 🍌</li>
  <li>Cherry πŸ’</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Since react is working on our above-said rules, react will do the following

  1. Checks ul element type first. Since it is the same in both versions it proceeds to check its props. Since children are changed(Reference will be changed) it starts to check every li element
  2. Checks the first element of ul element i.e li in both version since the text content is changed from Banana 🍌 to Apple 🍎, it updates the change to the DOM. Then it proceeds to check the next element
  3. Now it checks the second li element and updates the text change to the DOM from Cherry πŸ’ to Banana 🍌
  4. Then it finds out that there is a new element created at the bottom. So it creates a new li element and appends the element to the ul element.

Have you noticed anything unusual in this behaviour? Apple is the one that was appended to the first but react is updating the other two items unnecessarily, right? i.e Instead of performing a single update, react is performing three updates.
To avoid this react has introduced the key to uniquely identify each element.

Elements of the same type but with different keys will be uniquely identified and updated now. So if we introduce key to the above example

<ul>
  <li key={1}>Banana 🍌</li>
  <li key={2}>Cherry πŸ’</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

to

<ul>
  <li key={0}>Apple 🍎 </li>
  <li key={1}>Banana 🍌</li>
  <li key={2}>Cherry πŸ’</li>
</ul>
Enter fullscreen mode Exit fullscreen mode

Now react while comparing the first element knows that Apple 🍎 is newly added to the list and performs that single update.

Please do note that using index as key may create some issues especially when each of your components has an internal state and reorders between list is pretty common. Check this codepen for more details.

In the next article, we will try to create a naive react algorithm or the algorithm which relies on recursion by implementing the above concepts.

*P.S: This blog-series is largely inspired from this amazing blog written by Max Koretskyi *

Top comments (0)