How React Works Internally
Most people use React without understanding what happens behind the scenes. That is fine for small projects, but understanding React's internals helps you write faster apps and debug problems that otherwise feel mysterious. This topic explains what happens from the moment you write a component to the moment users see it on screen.
The Browser DOM: The Problem React Solves
The browser renders pages using the Document Object Model, or DOM. The DOM is a tree of all the HTML elements on the page. Changing DOM nodes directly is slow — the browser recalculates layout and repaints the screen every time something changes.
Imagine a large spreadsheet. Every time you change one cell, the entire spreadsheet recalculates and redraws. That is exactly what browsers do with the DOM. React's job is to make those updates fast.
The Virtual DOM
React keeps a lightweight copy of the real DOM called the Virtual DOM. It lives in JavaScript memory, not in the browser.
How the Virtual DOM works — step by step
User interaction or state change
|
v
React creates a NEW Virtual DOM tree
|
v
React compares new tree with OLD Virtual DOM tree
(This step is called "Diffing")
|
v
React finds only the CHANGED parts
|
v
React updates ONLY those parts in the real DOM
(This step is called "Reconciliation")
|
v
Browser repaints only the changed area
Think of it like an editor reviewing a document. Instead of rewriting the whole document every time you fix a typo, the editor finds the one word that changed and corrects only that word.
JSX is Not HTML
When you write JSX in a React component, the browser cannot read it directly. A tool called Babel transforms your JSX into plain JavaScript React.createElement() calls before the browser ever sees it.
What you write
const element = <h1>Hello World</h1>;
What Babel turns it into
const element = React.createElement("h1", null, "Hello World");
React.createElement() creates a plain JavaScript object that describes what the element should look like. This object becomes a node in the Virtual DOM tree.
The React Fiber Architecture
React 16 introduced an internal engine called Fiber. Before Fiber, React had to finish all rendering work in one go. If a complex update took too long, the page would freeze.
Fiber broke rendering into small chunks of work that can be paused, prioritized, and resumed. Think of it as a smart task scheduler.
Fiber Priority System – like a hospital triage desk
HIGH PRIORITY (must process immediately)
└── User clicks a button
└── User types in an input box
NORMAL PRIORITY (process soon)
└── Data loaded from an API
└── Animation frames
LOW PRIORITY (process when free)
└── Pre-loading off-screen content
└── Background data sync
This is why React apps feel responsive even when complex updates happen in the background.
Reconciliation: How React Decides What Changed
When state or props change, React re-renders the component and produces a new Virtual DOM tree. It then compares this tree with the previous one using a process called reconciliation.
Two key rules React follows during reconciliation
Rule 1: Elements of different types get destroyed and rebuilt
// Before
<div>Hello</div>
// After
<p>Hello</p>
// React destroys the div and creates a fresh p element
Rule 2: Elements of the same type get updated in place
// Before
<button className="blue">Click</button>
// After
<button className="red">Click</button>
// React only updates the className, not the whole element
Why Keys Matter in Lists
When React renders a list of items, it needs a way to identify each item uniquely across renders. Without keys, React re-renders every list item even when only one changed.
// BAD – no keys, React cannot track items
{items.map(item => <li>{item.name}</li>)}
// GOOD – keys let React track each item
{items.map(item => <li key={item.id}>{item.name}</li>)}
Think of keys like student roll numbers. A teacher marks attendance faster with roll numbers than with names alone.
The React Render Cycle
Every component in React goes through a predictable cycle:
RENDER PHASE
React calls your component function
React builds the Virtual DOM tree
(No side effects happen here)
COMMIT PHASE
React updates the real DOM
React runs useEffect callbacks
(Side effects happen here)
The render phase can happen multiple times before committing. The commit phase happens only once per update cycle.
What Triggers a Re-render
React re-renders a component when any of these things happen:
- The component's state changes via
useStateoruseReducer - A prop passed to the component changes
- The component's parent re-renders
- A context value the component reads changes
React does not re-render a component just because time passes. A re-render always has a cause.
React Root: Where Everything Starts
Every React app attaches to one real DOM element — usually a div with the id of root.
// index.html
<div id="root"></div>
// main.jsx
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")).render(<App />);
React takes over that div completely and manages everything inside it.
Summary
React keeps a Virtual DOM in memory and compares it with the previous version every time something changes. It updates only the parts that actually changed in the real browser DOM. The Fiber engine makes this process smart and responsive by breaking work into prioritized chunks. JSX is converted to JavaScript by Babel before the browser runs it. Understanding these mechanics helps you write React code that performs well and behaves predictably.
