Why React?
Declarative UI, component reuse, and what you give up for them.
What you will be able to do
- Explain why keeping a growing UI in sync by hand becomes hard
- Describe how declarative UI removes that coordination work
- Build one reusable component and render it with different data
- Split a large screen into small, composed components
- List what React gives you and what it leaves to other tools
- Name the trade-offs of choosing React, and when they are not worth it
The idea, in plain English
Lesson 1 showed the idea on a single counter: describe the UI for the current state, and React updates the page. On one counter that is a nicety. This lesson is about why it becomes a necessity as an app grows - and what it costs you.
Take one action on a learning platform: a learner completes a lesson. The lesson row, the module progress, the course progress, the dashboard, an achievement badge, and a notification all need to change. Written by hand, that is a chain of updateLesson(), updateModuleProgress(), updateCourseProgress() calls, and every new screen adds another one to remember. Forget one, and the page quietly disagrees with itself.
React removes that chain. Each of those pieces describes itself from the same data, so when the data changes they all follow. You stop asking "which elements do I need to change?" and start asking "what should the screen look like now?" - and that shift is the single biggest reason React exists.
The second reason is reuse. A CourseCard written once can show React, Node.js, and Python by being given different data, and a course page can be composed from small pieces - a header, a module list, a progress bar - each with one job.
None of that is free. React brings a build step, a toolchain, and a set of new concepts, and it does not make an app fast or well-structured on its own. For a mostly static page it is overhead with no payoff. Choosing it well means knowing both columns of that ledger.
Worked example: Rewriting a jQuery-style progress widget as a React component.
The coordination problem
Direct DOM updates are fine one at a time: set a title, set a percentage, disable a button. The trouble starts when several parts of the page depend on the same piece of data, because each of them needs its own update code - and that code has to run in the right place every time the data changes.
A search box that filters courses, a selection that changes the title, description, lesson count, progress, sidebar, breadcrumb, and URL - each change fans out across the page. The work is not in any single update; it is in remembering all of them.
That is the problem React is built for: making the page a function of the data, so there is nothing to remember.
Declarative, briefly revisited
Lesson 1 covered the core distinction; one table is enough here. Imperative code says how to change the page. Declarative code says what the page should be.
A login switch shows it well. Imperatively, you find the heading and the button and swap their contents on click. Declaratively, the component simply says: if loggedIn, show a welcome; otherwise show a Login button. There is no switching code at all - the state decides.
What you writeImperative: how to change the page. Declarative: what the page should be.Who coordinates updatesImperative: you. Declarative: React.In codeImperative: element.textContent = user.name. Declarative: <h1>{user.name}</h1>.As the UI growsImperative: more update paths to keep in step. Declarative: components describe themselves.Reuse: one component, many uses
Without components, a styled button is copied into every place it appears, and a change to it means finding every copy. A Button component puts that structure in one place; each use supplies only what differs - here, its label, passed as children.
The same goes for a whole card. One CourseCard, given title, lessons, and level, can render every course on the platform. You do not want ReactCourseCard, NodeCourseCard, and PythonCourseCard - you want one component and different data.
The values passed in are called props. They get a full lesson in Module 2; for now, read them as "the data this particular use of the component shows".
Tip: If you are about to copy a component and change a few words, that is the sign those words should become props.
Composition: small pieces with one job each
A course page does not have to be one component. It can be a CourseHeader, a CourseDescription, a ModuleList of Module components, and a CourseProgress - each small enough to understand, test, and change on its own.
The payoff shows up when something breaks. A bug in the progress bar sends you straight to CourseProgress, not into a 1,500-line file. Small components help maintenance, reuse, testing, collaboration, and debugging all at once.
What React gives you, and what it does not
React gives you a programming model: components, props, state, declarative rendering, and composition. Those five ideas are most of what this course builds on.
It does not give you a backend, a database, authentication, routing, global state, payments, or hosting. Real apps pair React with other tools - React Router, Redux or TanStack Query, a REST or GraphQL API, a server such as Node.js and Express, and a database such as PostgreSQL. Which ones depends on the app.
ComponentsFrom React. Reusable pieces of UI.Props and stateFrom React. Data passed in, and data a component owns.Declarative renderingFrom React. UI described from data, DOM updated for you.RoutingNot included. Usually React Router, or a framework such as Next.js.Server data and global stateNot included. TanStack Query, Redux, or Context.Backend, database, authNot included, and not the job of a UI library at all.What you give up
A plain page needs HTML, CSS, and JavaScript. A React app adds Node.js, npm, JSX, a bundler, a build process, and usually routing and testing setup. For a small or mostly static site, that is complexity with nothing to show for it.
There is a learning curve. A ten-line component can already involve functions, props, state, JSX, conditional rendering, event handling, and hooks - which is why React feels harder than plain JavaScript at first.
And React guarantees neither speed nor good structure. Unnecessary renders, large bundles, and slow network calls are all possible in React, and so is a 2,000-line component. React gives you the tools; the design is still yours.
Watch out: "React makes apps fast" is a myth. React makes UI updates manageable. Performance is a design choice - the React Performance module covers it.
Syntax and examples
// Each piece of the page is found and changed separately...
document.querySelector('#title').textContent = 'React Course';
document.querySelector('#progress').textContent = '35%';
document.querySelector('#complete').disabled = true;
// ...and one user action has to remember every one of them.
function onLessonCompleted() {
updateLesson();
updateModuleProgress();
updateCourseProgress();
updateDashboard();
updateAchievement();
updateNotification(); // forget one, and the page disagrees with itself
}const message = document.querySelector('#message');
const button = document.querySelector('#button');
button.addEventListener('click', () => {
message.textContent = 'Welcome!';
button.hidden = true; // and remember to hide the button too
});function Welcome({ loggedIn }) {
// No switching code: the data decides what is shown.
return <div>{loggedIn ? <h1>Welcome!</h1> : <button>Login</button>}</div>;
}function Button({ children }) {
return <button className="primary-button">{children}</button>;
}
function Toolbar() {
return (
<div>
<Button>Save</Button>
<Button>Submit</Button>
<Button>Continue</Button>
</div>
);
}function CourseCard({ title, lessons, level }) {
return (
<article>
<h2>{title}</h2>
<p>{lessons} lessons</p>
<p>{level}</p>
<button>Start Learning</button>
</article>
);
}
function CourseList() {
return (
<div>
<CourseCard title="React" lessons={192} level="Beginner" />
<CourseCard title="Node.js" lessons={206} level="Intermediate" />
<CourseCard title="Python" lessons={75} level="Beginner" />
</div>
);
}function CoursePage() {
return (
<>
<CourseHeader />
<CourseDescription />
<ModuleList />
<CourseProgress />
</>
);
}
// A bug in the progress bar? Open CourseProgress, not a 1,500-line file.let progress = 0;
const progressElement = document.querySelector('#progress');
const button = document.querySelector('#complete');
button.addEventListener('click', () => {
progress += 10;
// State, DOM lookup, event handling, and DOM update - all this code's job.
progressElement.textContent = `Progress: ${progress}%`;
});import { useState } from 'react';
function Progress() {
const [progress, setProgress] = useState(0);
// progress -> UI. Nothing here finds or edits an element.
return (
<div>
<p>Progress: {progress}%</p>
<button onClick={() => setProgress(progress + 10)}>Complete Lesson</button>
</div>
);
}
export default Progress;Tip: The question to carry into every React component: what should the UI look like for this state? If you find yourself asking which element to change, step back to the state.
Watch out: React still updates the DOM - it simply does it for you. Using React means you rarely write DOM code, not that the DOM stops mattering.
The five ideas React gives you
Each has its own lessons later in the course; this is the map.
ComponentsReusable pieces of UI.
<CourseCard />
PropsData given to a component by whoever uses it.
<CourseCard title="React" />
StateData a component owns and can change.
const [count, setCount] = useState(0);
Declarative UIThe UI described from data.
<h1>{count}</h1>CompositionBuilding bigger components out of smaller ones.
<CoursePage>...</CoursePage>
Try it yourself
The code does not change. Swap the content string and the program does something else entirely.
“In the DOM-style progress widget, also show the progress in a second place - a heading, say. Count the lines you had to add. Then do the same in the React version.”
“Look at any page you use daily and find three things that look the same but show different data. Each is a component waiting to happen - what would its props be?”
“Pick a site that would be worse built in React. Write down what it would cost and what it would gain.”
What usually goes wrong
ReactCourseCard, NodeCourseCard, PythonCourseCard - three copies of one idea. The parts that differ belong in props.
✗ function ReactCourseCard() { /* ... */ }
function NodeCourseCard() { /* ... */ }✓ <CourseCard title="React" lessons={192} />
<CourseCard title="Node.js" lessons={206} />React makes splitting easy, but it does not do the splitting for you. A 2,000-line component is still possible - and still painful.
Unnecessary renders, large bundles, and slow requests are all possible in React. Speed comes from design, not from the library.
Routing, server data, auth, and storage all come from elsewhere. Plan them from the start rather than discovering them later.
A mostly static page gains a build step and a bundle and nothing else. The trade-off only pays when the page is interactive and data-driven.
Best practices
- Describe the UI from data, and change the data rather than the page.
- When two components differ only in what they show, make one component with props.
- Give each component one job, small enough to name clearly.
- Compose pages from small components instead of growing one large one.
- Choose React for its component and state model - not by default, and not for speed.
Practice
Write these yourself before opening anything. Getting them wrong first is most of how this sticks.
Write a Button component that takes its label as children, and use it for Save, Submit, and Continue.
Show hintHide hint
Whatever sits between the opening and closing tags arrives as the children prop.
Show solutionHide solution
function Button({ children }) {
return <button className="primary-button">{children}</button>;
}
function Actions() {
return (
<div>
<Button>Save</Button>
<Button>Submit</Button>
<Button>Continue</Button>
</div>
);
}Rewrite element.textContent = user.name declaratively, inside a component that receives user.
Show hintHide hint
Describe the heading from the data instead of changing an element.
Show solutionHide solution
function UserName({ user }) {
return <h1>{user.name}</h1>;
}Sketch a course page as a tree of four or five components, then write the top-level CoursePage.
Show hintHide hint
Name each part by its job - header, description, module list, progress.
Show solutionHide solution
// CoursePage
// ├── CourseHeader
// ├── CourseDescription
// ├── ModuleList
// └── CourseProgress
function CoursePage() {
return (
<>
<CourseHeader />
<CourseDescription />
<ModuleList />
<CourseProgress />
</>
);
}A reusable course list
Render three courses from one data array using a single reusable CourseCard, then let the learner pick one.
- Keep the courses in one array of objects with title, lessons, and level.
- Write one CourseCard component and use it for every course - no per-course components.
- Each card shows the title, "N lessons", the level, and a Start Learning button.
- Bonus: clicking Start Learning shows "You selected React" (or whichever course was chosen).
const courses = [
{ title: 'React', lessons: 192, level: 'Beginner' },
{ title: 'Node.js', lessons: 206, level: 'Intermediate' },
{ title: 'Python', lessons: 75, level: 'Beginner' },
];
function CourseCard(/* props */) {
// title, "N lessons", level, and a Start Learning button
}
function CourseList() {
// render one CourseCard per course
}Show one solutionHide solution
import { useState } from 'react';
const courses = [
{ title: 'React', lessons: 192, level: 'Beginner' },
{ title: 'Node.js', lessons: 206, level: 'Intermediate' },
{ title: 'Python', lessons: 75, level: 'Beginner' },
];
function CourseCard({ title, lessons, level, onStart }) {
return (
<article>
<h2>{title}</h2>
<p>{lessons} lessons</p>
<p>{level}</p>
<button onClick={() => onStart(title)}>Start Learning</button>
</article>
);
}
function CourseList() {
const [selected, setSelected] = useState(null);
return (
<div>
{courses.map((course) => (
<CourseCard
key={course.title}
title={course.title}
lessons={course.lessons}
level={course.level}
onStart={setSelected}
/>
))}
{selected && <p>You selected {selected}</p>}
</div>
);
}
export default CourseList;
// One component, three courses. The data varies; the structure does not.Key points
- Keeping many parts of a page in sync by hand gets harder with every feature; React makes the page a function of the data instead.
- Declarative UI replaces "which element do I change?" with "what should the screen look like now?".
- One component, given different props, can render many different items.
- Composing small components with one job each makes code easier to maintain, test, and debug.
- React gives you components, props, state, declarative rendering, and composition - and nothing else.
- Routing, server data, auth, and storage come from other tools.
- React costs a toolchain and a learning curve, and guarantees neither speed nor good structure.
- For a small, mostly static page, plain HTML, CSS, and JavaScript is the better choice.
Quick check before you move on
Interview questions
Why was React created?
To make complex, interactive UIs manageable. Instead of coordinating every DOM update by hand, you describe the UI from data with reusable components, and React keeps the page in step.
What is declarative programming?
Describing the result you want rather than the steps to produce it. In React, you describe what the UI should be for the current state.
What is imperative UI?
Controlling exactly how the UI changes, usually through direct DOM operations such as finding an element and setting its text.
What is component reusability?
Writing a UI component once and using it in many places with different data or configuration, passed in as props.
Does React eliminate DOM manipulation?
It removes most of it from your code, but React itself still updates the DOM - it works out the minimal changes and applies them for you.
What is a disadvantage of React?
It adds tooling and concepts - a build step, JSX, state, and a learning curve - that are unnecessary for small or mostly static sites. It also does not guarantee performance or good architecture on its own.
Quiz
- 1.
Which programming style does React primarily encourage? A. Imperative B. Declarative C. Procedural SQL D. Assembly
- 2.
Which approach directly tells the DOM what to change? A. Declarative B. Imperative C. Functional component D. JSX
- 3.
What is a major advantage of React components? A. They automatically create databases B. They make UI pieces reusable C. They replace JavaScript D. They remove the need for CSS
- 4.
Is <CourseCard /> a reusable React component? A. Yes B. No
- 5.
Which statement is correct? A. React automatically provides a backend B. React automatically provides PostgreSQL C. React primarily focuses on UI D. React replaces HTTP APIs
- 6.
Which is generally easier to maintain? A. One huge component containing the entire application B. Well-designed components with clear responsibilities
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