Understanding React — From Why It Exists to How It Actually Works
Before you can really understand React, it helps to understand why it exists in the first place. Not just “it’s a component framework”, but what problem it was actually solving when it was created.

Why React Exists
Before React came along, building complex UIs was done by writing a lot of jQuery or vanilla JavaScript code and as applications grew, things started to fall apart pretty quickly.
DOM manipulation was unpredictable. Every time something changed, such as a user clicked a button or data came back from an API, you had to manually find the right DOM elements and update them.
Code had no structure or reusability. If you built a dropdown or a modal, there was no clean way to reuse it and you’d end up copy pasting and maintaining the same thing in multiple places.
React came along and changed the way we think about UI. Instead of manually updating the DOM every time something changes, you just describe what the UI should look like for a given state and React handles the rest.
React is built around three core ideas:
- Component-based architecture: split your UI into isolated, reusable pieces.
- Declarative programming: describe what the UI should look like, not how to update it.
- Virtual DOM: a lightweight copy of the real DOM that makes updates fast.
Component-Based Architecture
We split the UI into isolated and reusable components, where each component manages its own structure, styling and behaviour. Think of it like building with Lego, you create individual pieces and compose them together to build something bigger.
A component is just a JavaScript function that returns UI. A button, a nav bar, a modal, an entire page section, all components. You build them once and reuse them anywhere in your app. If the button needs to change, you change it in one place and every instance of it updates automatically.
Because each component manages its own logic internally, a bug in one component doesn’t bleed into another. You can also test them individually, which makes debugging significantly faster than hunting through a sprawling jQuery file trying to figure out which line broke the dropdown.

Declarative vs Imperative
This is one of the most important mental shifts when moving from vanilla JavaScript to React. So what do these two terms mean?
Vanilla JavaScript and jQuery are imperative, meaning that when you write code you tell the computer every step. “Find this element, change this class, update this text.” You’re in charge of how it happens.
// Imperative — vanilla JS
// you manually find the element and update it yourself
const btn = document.getElementById('like-btn');
btn.addEventListener('click', () => {
const count = document.getElementById('count');
count.textContent = parseInt(count.textContent) + 1;
});
On the other hand, React is declarative, meaning that you just describe what you want the UI to look like and React figures out how to get there. You stop worrying about the steps and just say “when this state is true, the UI should look like this.”
// Declarative — React
// you just describe what the UI should look like
function LikeButton() {
const [likes, setLikes] = useState(0);
return <button onClick={() => setLikes(likes + 1)}>{likes} likes</button>;
}
The Virtual DOM and Reconciliation
When you interact with a page, such as clicking a button, typing in a form, something on the screen needs to update. To make that happen, the browser has to touch the DOM and that’s not cheap. Every time it does, the browser has to recalculate layouts, repaint elements, recomposite layers. The more of that happening at once, the slower things get.
React’s solution to this problem is the Virtual DOM. Instead of touching the real DOM every time something changes, React keeps a lightweight copy of it in memory, a JavaScript object that mirrors the structure of your actual page.
Here’s what happens when state changes:
- React builds a new virtual DOM based on the new state
- It compares that with the previous virtual DOM (this is called reconciliation)
- It figures out the minimum number of changes needed
- Only then does it touch the real DOM and only the parts that actually changed

The Component Lifecycle
Every React component goes through three phases:
Mount — the component appears on screen for the first time. Think of it like a component being created. React creates it, adds it to the DOM, and it’s now visible. Any useEffect with an empty dependency array fires after this — it's your chance to do something once when the component first appears, like fetching data or starting a timer.
Update — something changes. State updates, new props come in. React re-renders the component, diffs the new virtual DOM against the old one, and updates only what changed on screen.
Unmount — the component is removed. Maybe the user navigated away, maybe a condition changed and it’s no longer needed. React removes it from the DOM. Before it does, any cleanup functions in useEffect run — this is your chance to tidy up anything the component was doing.
PS: This is based on my own research and understanding of why React exists and how it works. I’d always recommend double checking other resources if you want to go deeper. I wrote this mostly for myself, but if it helps someone else along the way, that’s a win. Thanks for reading.