Behind the scenes of how react works.
February 11, 2023Let's start with the basics by understanding what a component is and how it works.
A component is like a blueprint or template of a UI that returns a React element in the element tree, it is usually written in JSX.
From blueprint, we can create one or multiple component instances
when we use the component.
Each component instance has its own state, props, and lifecycle methods mount, update/re-render, and unmount.

When using a component technically its a component instance each component instance will return a react element
.Component is usually
written in JSX however JSX in transplied to vanilla js with the React.createElement
function calls by the transpilers like babel or other transpilers.
So using component will return a react element that element is a imutable javscript object with necessary properties that react keeps in memory
to create DOM elements for the current component instance.
The term Virtual Dom is not used by react official docs anymore rather they say react tree. But i will use the term Virtual DOM because there will be so many tree in react and it might confuse some of you. 😁

💡 The
$$typeof
property in react element is used by react to prevent from cross site scripting attacks. notice that the value of the property isSymbol
which is a primitive data type in js which cannot be transmitted via JSON. That means these symbol cannot come from any API call.So if a hacker send the fake component from any api react will not see the typeof:Symbol property and not add that fake react element to the DOM.
Let's now discuss the subject I mentioned in the component flowchart figure. Basically we will learn steps of how react renders the ui. Just keep in mind that rendering term doesnot mean its updating the real DOM directly or produces any visual changes instead there are some important process invloved while rendering.
1. Render triggered
Rendering process is started by react when a render is triggered mostly on the initial render and state update in any component instances also called re-render. Render triggred is for entire applications but does not update the dom for all.
2. Render Phase
In this process react calls the component functions and figures out how DOM should be updated to reflect the state changes however it doesnot update the
real dom in this phase, it happens internally it does not produces any visual changes. In the beginning react goes through the entire component tree take all the
component instances that causes render and this will create updated react elements and all together it will create a js object also called Virtual DOM
.
Virtual Dom is a tree of all react element created from all the instances from the component tree.
Virtual Dom is cheap and fast to create multiple trees even if the component tree is very huge.

Updating a state in a parent component causes all of its children to be re-render even if children's state or props are not change.
So again when a state changes in somewhere in application it will create a new virtual dom which is cheap and fast however writing to the DOM
is not cheap and fast. For example in a large complex app a state changed somewhere it would be extremly unoptimized and wastefull to write to the DOM from scratch,
only a small portion of the DOM should be updated the rest should be resued except for inital render.
And thats what react exactly what react will do with the process called Reconcilation
.
Reconcilation is a process of deciding which DOM elements needs to be inserted, updated, and deleted with a latest state changes with help of
fiber(React v16+)
and the diffing
algorithm. Now lets cover the process after Virtual DOM is created, On the inital render of the application,
based on that virtual dom, fiber creates another tree which is called Fiber tree
.It is special internal tree where for each component instance and Dom element
there is one fiber. unlike virtual dom fiber tree is not re created on every render, it is never destroyed because it is mutable data structure which gets mutated on every
render. i said each component instance hold its own state props at beginning but internally fiber is the one that takes care of it since there is each fiber for each component
instance has its props, state, side effects, hooks and work queue.

3. Commit Phase
In this phase react writes the DOM to insert ,update or delete some elements in order to keep sync the state with the application by sending the list of dom updates to do in the current fiber tree.
Before the commit phase react library was handling the rendering process but commit phase is handle by react dom
. React itself does not touch the DOM nor Native Platfrom (iOS and andriod).
React does even know where the result of render phase will be committed and painted, only render phase is handled by react because it was designed to be used independently for multiple platform.
Meaning react can be used to develop web applications using react dom, similarly react native to develop iOS and andriod applications with the Native components like View, Image, Pressable, etc .
and even videos using Remotion.
4. Browser Paint
In this phase the browser will notice that the DOM has been updated so it repaints the screen, this phase has nothing to do with react but this final step that users see the changes in the browser.If you want to know more about how this is handled by browsers, you can click here.

Diffing
I mentioned about diffing algorithm in the reconcilation process but did not talked much about it. Of course diffing algorithm is very complex so i will just discuss the basics like what is diffing algorithm and how it works. Diffing algorithm is part of reconcilation process. Diffing is comparing between elements step by step between two renders based on their position in the react tree. Diffing algorithm uses two basic assumptions:
1. Two element of different element type will produce different tree
When changing the div to header the element type is changed so it will distroy the tree from the parent component, rebuild with the new parent header from div in this example and also its state will be reset.
<>
<div>
<SearchBar />
</div>
<main>lorem</main>
</>
<>
<header>
<SearchBar />
</header>
<main>lorem</main>
</>
There are many senarios where same position and same element will be present in the element tree those elements will not be destroyed nor their state. meaning the component's state will be preserved.
<>
<header className="hidden">
<SearchBar />
</header>
<UserProfile/>
</>
<>
<header className="active">
<SearchBar />
</header>
<UserProfile/>
</>
You may see as the element has changed from the above example but actually only the className attribute has been changed not the element type. And this behaviour is absolutely needed because when the prop and attribute changed it does not makes sense to change the whole element, react will simply mutate the react tree remember which is simply a mutable javscript object.
2. Element with stable key prop stays the same in every render
From the above explanation you guys should be clear about two things in diffing algorithm:
- Different element in will produce different tree and its state,props and attributes will be destroyed.
- Same element in the same position will not produce different tree and its state will be preserved but props and attributes can be updated.
Same element in the same position means state is preserved so that is the standard way of updating the tree by react. However we donot want this behaviour in our application for examples mapping a list and displaying a component, tabbed component, accordion etc.
Let's see clearly with a code example:
{
activeTab <= 1 ? (
<TabContent item={content.at(activeTab)} />
) : (
<DifferentElementType />
);
}

In the above example there are TabContent component which are of same element type. The TabContent has its own title, body and likes state . But did you notice in the picture that the likes of one TabContent is same on another TabContent. So its clearly an issue where we want to reset the state in another TabContent. These types of situation will come when we map a list item and in accordion or other similar components.
So to solve that issue the key
prop comes.
{
activeTab <= 1 ? (
// added key prop
<TabContent item={content.at(activeTab)} key={content.at(activeTab).id} />
) : (
<DifferentElementType />
);
}

Notice after adding key prop the state of TabContent is reset when we render same
element in same tree position. that is because after adding unique key
to the element
react treats the element as a different element so the tree is changed and so the state also. So thats
why we add the key prop while mapping a list or in a tab or accordion component when
we want to reset the state. However the value should be really unique not like index
that we get as an second argument in map function but a unique id like one from uuid
package.
References
- Render and commit react docs
- CrossComm, Inc: Understanding React's UI Rendering Process
- If you want to see the example code you can see the codesandbox
If you liked it share it with your friends or colleague