Introduction to React
What React is, what it is not, and the problem it was built for.
What you will be able to do
- Explain what React is, and why it is called a library rather than a framework
- Describe the problem React was built to solve
- Tell imperative and declarative UI code apart
- Explain what a component is, and how components form a tree
- Describe what React does when state changes
- Build the same counter in plain JavaScript and in React
- Judge when React is worth using and when it is not
The idea, in plain English
React is a JavaScript library for building user interfaces. It was created at Facebook, is now open source, and has one central idea: you describe what the screen should look like for the data you have, and React takes care of changing the page to match.
That sounds small, and for a single counter it is. The difficulty it solves appears as an app grows. A learning platform has a profile, courses, modules, lessons, quizzes, progress, and notifications, and each of them depends on data that changes. Written by hand, every change means finding the right elements and updating them in the right order, and forgetting one leaves the screen out of step with the data.
React replaces that bookkeeping with a rule you can hold in your head: UI = f(state). The UI is a function of the current state. Change the state, and React runs your component again, compares the new result with the old one, and makes only the DOM changes that are actually needed.
The other half of React is components - reusable pieces of UI, written as JavaScript functions, that fit together into a tree. A page becomes a CoursePage made of a CourseHeader, a ModuleList, and a Progress bar, each small enough to understand on its own.
React is not a language and it does not replace JavaScript. Everything inside a component - map, filter, destructuring, async functions - is ordinary JavaScript, which is why the JavaScript course is the prerequisite for this one.
Worked example: The same counter written by hand and written in React.
Imperative against declarative
Imperative code tells the computer how to do something, step by step. For a counter: find the button, find the number, listen for a click, increase the count, then write the new count into the element. Every step is yours to get right.
Declarative code describes what the result should be. In React you write <h1>{count}</h1> and never touch the element again - when count is 3, the heading shows 3. You describe the destination; React works out the route.
The difference matters most when many things depend on the same data. Imperatively, each of them needs its own update code, and every new feature adds another place to forget. Declaratively, each piece describes itself from the state, so changing the state updates all of them.
ImperativeYou find elements and change them: countElement.textContent = count.DeclarativeYou describe the output from state: <h1>{count}</h1>.Who updates the DOMImperative: your code. Declarative: React.What you changeImperative: the page. Declarative: the state.Where bugs hideImperative: an update you forgot. Declarative: state that is wrong.Tip: A quick test: if your code reads document.querySelector or sets textContent, it is imperative. In a React component you should almost never need either.
UI = f(state), and what happens on a click
State is data a component owns that can change - here, the count. The component is a function that takes the current state and returns a description of the UI.
When you call setCount, React does not edit the page directly. It re-runs the component to get a new description, compares it with the previous one, and applies only the differences to the real DOM. For the counter that is a single text change.
That re-run is called rendering, and it is cheap and frequent by design. Much of this course is about understanding exactly when it happens and why.
Components and the component tree
A component is a function that returns UI. Welcome returns a heading; CourseCard returns a card. You use one by writing it like an HTML tag - <Welcome /> - and a component can contain other components.
Nesting components gives you a tree. App contains a Navbar, a Sidebar, and a CoursePage; the CoursePage contains a CourseHeader and a ModuleList; the ModuleList contains several Modules. Each part has one job, and the tree mirrors the layout of the page.
Component names start with a capital letter. That is how React tells <CourseCard /> - one of your components - from <div>, a built-in HTML element.
Watch out: A lowercase component name is treated as an HTML tag. function courseCard() rendered as <courseCard /> produces an unknown element, not your component.
A library, not a whole framework
React handles the UI layer and deliberately stops there. Routing, data fetching, global state, and testing come from other libraries - React Router, TanStack Query, Redux, Testing Library - which later modules cover.
It also stops at the browser. A real app talks over HTTP to a backend - Node.js and Express, say - which talks to a database such as PostgreSQL. React never touches the database directly.
This is why React is called a library rather than a framework: it does one job well and leaves you to choose the rest. Frameworks built on React, such as Next.js, make those choices for you.
When React is worth it, and when it is not
React earns its place when a page is interactive and data-driven: dashboards, forms, admin portals, e-commerce, and learning platforms, where many parts of the screen change as the user works.
It is overhead for a page that barely changes. A company homepage with About, Services, and Contact needs HTML and CSS, and adding React brings a build step and a bundle for no benefit.
The question to ask is not "can I use React?" but "does this app benefit from components and state-driven updates?".
Syntax and examples
<!DOCTYPE html>
<html>
<head>
<title>Counter</title>
</head>
<body>
<h1 id="count">0</h1>
<button id="increment">+</button>
<button id="decrement">-</button>
<script src="app.js"></script>
</body>
</html>let count = 0;
// Find every element we will need to change.
const countElement = document.querySelector('#count');
const incrementButton = document.querySelector('#increment');
const decrementButton = document.querySelector('#decrement');
incrementButton.addEventListener('click', () => {
count++;
countElement.textContent = count; // we must remember to update the page
});
decrementButton.addEventListener('click', () => {
count--;
countElement.textContent = count; // ...every time, in every handler
});import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
// No querySelector, no textContent: describe the UI for this count.
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(count - 1)}>-</button>
</div>
);
}
export default Counter;User clicks +
↓
setCount(1) state changes
↓
Counter() runs again React renders the component
↓
<h1>1</h1> the new description
↓
React compares it with <h1>0</h1>
↓
One text change is applied to the real DOMfunction Welcome() {
return <h1>Welcome to React</h1>;
}
function CourseCard() {
return (
<div>
<h2>React Course</h2>
<p>Learn React from fundamentals to advanced concepts.</p>
</div>
);
}
// Used like HTML tags - the capital letter tells React they are components.
function App() {
return (
<main>
<Welcome />
<CourseCard />
<CourseCard />
</main>
);
}function CoursePage() {
return (
<div>
<CourseHeader />
<ModuleList />
<Progress />
</div>
);
}
function ModuleList() {
return (
<div>
<Module />
<Module />
<Module />
</div>
);
}
// CoursePage
// ├── CourseHeader
// ├── ModuleList
// │ ├── Module
// │ ├── Module
// │ └── Module
// └── Progressconst courses = ['React', 'Node.js', 'Python'];
function CourseList() {
return (
<ul>
{/* courses.map is ordinary JavaScript */}
{courses.map((course) => (
<li key={course}>{course}</li>
))}
</ul>
);
}Tip: Keep the mental model in one line: change the state, and React changes the page. If you catch yourself editing the page directly, look for the state you should have changed instead.
Watch out: useState is used here only to show the idea. It gets a full lesson of its own in Module 3 - for now, read it as "a count that React keeps track of".
Terms used from here on
Each gets its own lesson later; this is enough to follow along.
ReactA JavaScript library for building user interfaces.
ComponentA reusable piece of UI, written as a function.
function Welcome() {}JSXHTML-like syntax for describing UI inside JavaScript.
<h1>{count}</h1>StateData a component owns that can change over time.
useState(0)
PropsData passed from a parent component to a child.
<CourseCard title="React" />
RenderReact running a component to work out what the UI should be.
DOMThe browser structure of the page, which React updates for you.
EventSomething the user or browser does, such as a click or a keypress.
onClick={handleClick}Try it yourself
The code does not change. Swap the content string and the program does something else entirely.
“In the plain JavaScript counter, count how many lines update the page. Now add a second place that shows the count - a page title, say - and count again. Do the same in the React version.”
“In the vanilla counter, delete one textContent line and click the button. The count changes but the page does not - that gap is the bug React is designed to remove.”
“Pick any page you use daily and sketch it as a component tree: what is the top component, and what are its three or four children?”
What usually goes wrong
React is a library written in, and used from, JavaScript. The language you write is JavaScript with JSX on top.
Everything around the JSX - arrays, objects, map, destructuring, async code - is plain JavaScript. Weak JavaScript shows up as confusing React.
Reaching for the DOM fights React, which will overwrite your change on the next render. Change state and let the page follow.
✗ document.querySelector("#count").textContent = count;✓ const [count, setCount] = useState(0);
// ...
<h1>{count}</h1>React treats lowercase tags as HTML elements, so a lowercase component is silently rendered as an unknown tag.
✗ function courseCard() { /* ... */ }
<courseCard />✓ function CourseCard() { /* ... */ }
<CourseCard />A mostly static page gains a build step and a JavaScript bundle and nothing else. Choose the tool from what the page needs to do.
Most early React confusion is really JavaScript confusion. Be comfortable with functions, arrays, objects, map, filter, destructuring, spread, modules, and promises first.
Best practices
- Describe the UI from state; do not edit the page directly.
- Start component names with a capital letter.
- Keep each component small enough to explain in one sentence.
- Think of a page as a tree of components before writing any of them.
- Reach for React when a page is interactive and data-driven, not by default.
- Keep your JavaScript strong - it is most of what you write in React.
Practice
Write these yourself before opening anything. Getting them wrong first is most of how this sticks.
Write a Welcome component that returns an h1 saying "Welcome to React", and render it twice inside an App component.
Show hintHide hint
A component is a function that returns JSX; you use it like a tag with a capital letter.
Show solutionHide solution
function Welcome() {
return <h1>Welcome to React</h1>;
}
function App() {
return (
<div>
<Welcome />
<Welcome />
</div>
);
}Rewrite this imperative snippet declaratively: `const el = document.querySelector("#greeting"); el.textContent = "Hello, " + name;`.
Show hintHide hint
Describe what should be shown for a given name, instead of finding and changing an element.
Show solutionHide solution
function Greeting() {
const name = 'Ravi';
return <p>Hello, {name}</p>;
}Sketch the component tree for a course page with a header, a list of three modules, and a progress bar, then write the CoursePage component.
Show hintHide hint
One top component, with each part as its own child component.
Show solutionHide solution
// CoursePage
// ├── CourseHeader
// ├── ModuleList (three Module components)
// └── Progress
function CoursePage() {
return (
<div>
<CourseHeader />
<ModuleList />
<Progress />
</div>
);
}Counter with reset
Build the counter in React, then extend it with a reset button - once in plain JavaScript and once in React, so you feel the difference.
- Show "Counter: 0" when the page loads.
- The + button adds one and the - button subtracts one.
- A Reset button sets the count back to 0.
- In the React version, do not use document.querySelector or textContent anywhere.
- Bonus: in the plain JavaScript version, count how many places update the page, and compare.
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Counter: {count}</h1>
{/* add the -, +, and Reset buttons */}
</div>
);
}
export default Counter;Show one solutionHide solution
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Counter: {count}</h1>
<button onClick={() => setCount(count - 1)}>-</button>
<button onClick={() => setCount(count + 1)}>+</button>
<button onClick={() => setCount(0)}>Reset</button>
</div>
);
}
export default Counter;
// Every button only changes the state. The heading is never touched
// directly - it is described once, and React keeps it in step.Key points
- React is a JavaScript library for building user interfaces - not a language, and not a replacement for JavaScript.
- React is declarative: you describe the UI for the current state, and React updates the DOM.
- UI = f(state): change the state and the component renders again.
- On a render, React compares the new result with the old and changes only what differs.
- A component is a function that returns UI, and components nest into a tree.
- Component names start with a capital letter.
- React handles the UI layer; routing, data fetching, and state libraries sit alongside it.
- Use React when a page is interactive and data-driven; a static page does not need it.
Quick check before you move on
Interview questions
What is React?
A JavaScript library for building user interfaces from reusable components, using a declarative model: you describe the UI for the current state and React updates the DOM to match.
Is React a framework?
It is usually called a library, because it focuses on the UI layer. Routing, data fetching, and state management come from other libraries, or from a framework built on React such as Next.js.
What problem does React solve?
Keeping a complex, interactive UI in step with changing data. Instead of hand-coding every DOM update, you describe the UI from state and React works out the minimal changes.
What is a component?
A reusable piece of UI. In modern React it is a JavaScript function that returns JSX, and components compose into a tree.
What is declarative UI?
Describing what the UI should look like for a given state, rather than the step-by-step DOM operations needed to get there.
Does React replace JavaScript?
No. React is written in and used from JavaScript; everything inside a component apart from the JSX is ordinary JavaScript.
Quiz
- 1.
React is primarily: A. A programming language B. A database C. A JavaScript library D. A backend server
- 2.
Which approach does React primarily encourage? A. Declarative UI B. Manual DOM manipulation C. SQL programming D. Server-side rendering only
- 3.
What is a React component? A. A database table B. A reusable piece of UI C. A CSS property D. An HTTP request
- 4.
Is courses.map(course => ...) normal JavaScript? A. Yes B. No
- 5.
What generally happens when React state changes? A. The browser restarts B. React renders the relevant component again C. The database is updated automatically D. The application is rebuilt
- 6.
Which is imperative DOM manipulation? A. <h1>{count}</h1> B. element.textContent = count; C. <CourseCard /> D. {courses.map(...)}
Comments
Sign in to leave a comment. Your name and photo come from Google; nothing else is shared.
Loading comments...
AI
System Design
Backend
- GraphQL8 modules · 69 lessons planned
- Core Python13 modules · 75 lessons planned
- FastAPI5 sections · 20 lessons
- Node.js14 modules · 206 lessons planned
- Node.js Performance7 chapters · 36 topics
- Event Loop Lifecycle6 phases · 3 scenarios
- Docker & Containerization11 modules · 144 lessons planned
- AWS for Developers14 modules · 219 lessons planned
- CI/CD & DevOps Automation10 modules · 134 lessons planned