Think You Understand React Re-rendering? Think Again...

You might’ve heard React developers throwing around terms like “Rendering,” “Re-rendering,” and “Virtual DOM” like it’s a secret club handshake. And you always nod along, thinking you probably get it... But deep down, there’s no clear picture in your head. So what’s actually going on? Let’s untangle the chaos.
You might be writing all your life syntax like below:
const jsx = () => <h1>Hello, World </h1>;
These are called JSX — a fancy abbreviation for JavaScript XML. It allows us to write HTML-like code inside JavaScript, which makes component structure easier to read and write.
However, browsers do not understand JSX directly. They can only interpret plain JavaScript.
To solve this, we have Babel — a compiler that transforms JSX into browser-friendly JavaScript. This allows our JSX code to run seamlessly in the browser.
But the bigger question is — How does Babel actually work behind the scenes?
Simply put, Babel takes the JSX code and compiles it into React.createElement
calls. These calls return plain JavaScript objects known as React elements.
You can just write code by calling React.createElement, or just let Babel do its job.
But wait... What is React.createElement?
Well, it's just a function that takes JSX and returns a React Element, which is just an object.
Let's Learn how your JSX gets converted into React. createElement syntax. Example
const jsx = () => <h1>Hello World!</h1>;
const element = React.createElement(h1, null, "Hello World!");
The above code can be generalized as:
React.createElement(type, props, ...children);
Let's break it down into each term:
- type - It's a string, generally it's the HTML tag. example - h1, div, etc
- props - Attributes like children, className, id, onClick, etc.
- ...children: Note this is an optional field; it can be text, components, or elements
Let's do a complex example:
<div className="container">
<h1>Hello</h1>
<p>Welcome to React</p>
</div>
const element = React.createElement(div, {className: 'container'} , React.createElement(h1, null "Hello"), React.createElement(p, null, "Welcome to React"));
By now, you probably have a good idea of how JSX gets converted into React.createElement
function calls. But the more important question is — What exactly do these function calls return? What is the actual output?
It returns an output like the one shown below. Remember, what we get from React.createElement
It's called a React element — and it's just a plain JavaScript object:
{
type:'',
props: {
},
key: '',
ref: ''
}
So our above example can be converted as:
const jsx = () => <h1>Hello World!</h1>;
const element = React.createElement(h1, null, "Hello World!");
{
type: "h1",
props: {
children: "Hello World!"
},
key : "",
ref: ""
}
Let's understand each key of the object:
- Type - Tells about the element, for example, h1, div, etc
- Props - This contains className, child elements, etc.
- Key: You might know this if you have rendered a list in React.
- Ref: You might know this if you have worked with useRef, direct access and interaction with the DOM.
I guess this all makes sense to you, let's dive into what actually is rendering?
In simple terms, React takes this React element object and converts it into a real DOM element — the one you actually see rendered on the screen or UI.
I bet if you have followed the whole tutorial, this would have made sense.
There are two types of rendering:
- Initial Rendering.
- Re-Rendering.
Let's cover Initial Rendering first:
function App() {
return <h1>Hello, World!</h1>;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
Steps:
App returns - <h1>Hello World!</h1>
and gets converted into -
{
type: 'h1',
props: {
children:'Hello world!'
}
}
- React creates a VIRTUAL DOM.
- React updates the REAL DOM and gets inserted into
#root
.
In large applications, there can be thousands of components with deep nesting. This results in a massive JavaScript object — a tree-like structure of React elements. Constructing the actual DOM from this large structure can be time-consuming. However, this construction typically happens only once during the initial render.
You might have noticed that the initial load of a React application often takes some time. This is because the initial render involves constructing the entire component tree and converting it into real DOM elements.
What is re-rendering, and why do we even need it?
Re-rendering is the process where a component updates and executes again to reflect changes in the UI. However, not every change triggers a re-render — React is optimized to re-render only when it's necessary, based on changes to state or props.
A component re-renders when:
- State changes.
- Props changes.
- Parent re-renders.
Let's dive into Virtual DOM now:
The Virtual DOM is a lightweight copy of the real DOM. It helps React efficiently update the UI by avoiding direct manipulation of the real DOM on every change. Instead, React compares the Virtual DOM versions and applies only the necessary updates to the real DOM.
But the question comes - how does this efficient updates takes place?
Step 1: Render Phase, i.e, Creating the V-DOM, representation of below:
{
type: "h1",
props: {
children: "Hello World!"
}
}
Step 2:Diffing (Compare Old and New Virtual DOM):
When state/props change, React creates a new VDOM and compares it with the previous Virtual DOM.
This comparison happens using the Reconciliation Algorithm.
Step 3: Patching the Real DOM:
React finds the differences and updates the changed parts in the Real DOM.
Example:
- If only text changes, we change text like - Count 0 to Count 1, if the tag changes, a new tag gets created.
We mentioned the Reconciliation algorithm, let's understand this:
Reconciliation is React's algorithm to efficiently update the Real DOM, keeping change minimal.
Reconciliation Steps:
- A new VDOM get created on state, props changes.
- Compare the old and new VDOM.
- Identify the changes (Diffing Algorithm)
- Update the changes on REAL DOM.
Let's understand the rules of Diffing Algorithm:
Rule 1: If Element type changes example h1 -> p, React destroys the old element and creates a new one.
Rule 2: If the type is the same, only text changes happen.
Rule 3: Lists are compared using keys, its is very important to track changes efficiently; no keys, then it's an inefficient reconciliation.
I guess now you know why the browser console always gives a warning when you forget to add keys.
That's all...
If you want to learn more topics or anything, Do send me a Hi on Linkedin..
Thanks