Lesson 1 • Beginner
Introduction to React ⚛️
By the end of this lesson you'll understand what React is and why it exists, read and write JSX, explain how the Virtual DOM makes updates fast, recognise a component as a function that returns UI, and spin up a brand-new React project with Vite.
What You'll Learn
- What React is and why declarative, component-based UI beats hand-writing the DOM
- How to read and write JSX — HTML-like syntax embedded in JavaScript
- What the Virtual DOM is and why it makes updates fast
- That a component is just a function that returns UI
- How to embed variables and expressions in JSX with { curly braces }
- How to create and run a new React project with Vite
.map() on an array is new to you, peek at the JavaScript course first. Everything React-specific, we'll build here from scratch.1️⃣ What React Is (and Why It Exists)
React is a JavaScript library for building user interfaces, created by Facebook (now Meta) in 2013. It powers Netflix, Instagram, Airbnb, Discord, and a huge slice of the modern web. It's a library, not a full framework — it focuses purely on the UI layer, which makes it flexible.
The big idea is being declarative. With plain JavaScript you write imperative code: you grab elements and manually change them step by step — find this element, set its text, add this class, remove that node. As an app grows, those hand-written DOM updates become a tangle of bugs.
React flips it around. You describe what the UI should look like for the current data, and React figures out the DOM changes for you. Change the data, and the UI updates to match — automatically. You stop micromanaging the page and start describing the result.
Imperative (vanilla JS) vs Declarative (React) — same goal:
// Imperative: YOU do every step by hand.
const h1 = document.querySelector("h1");
h1.textContent = "Hello, " + name + "!";
h1.classList.add("title");
// Declarative (React): you describe the result, React does the steps.
// <h1 className="title">Hello, {name}!</h1>2️⃣ Components Are Functions That Return UI
In React, everything is a component. A component is simply a JavaScript function that returns some UI. You build a page by nesting and reusing these functions — exactly like snapping LEGO bricks together. Here's a real one (read-only — it needs a build step to run):
📄 Read-only worked example — real React (does not run in the editor):
// App.jsx — your first REAL React component (read-only).
// A component is just a JavaScript FUNCTION that returns UI (JSX).
function App() {
// The returned JSX looks like HTML, but it's JavaScript underneath.
return (
<div>
<h1>Hello, React!</h1>
<p>My first component.</p>
</div>
);
}
// Make this component available to the rest of the app.
export default App;
// Two rules already on display here:
// 1) Component names start with a Capital letter -> App, not app.
// 2) The function MUST return JSX (the UI). No return = nothing renders.To prove a component is "just a function that takes inputs and returns UI", here's the same idea in plain runnable JavaScript — we return strings instead of JSX, but the shape is identical. Run it and change the names:
🧩 Try It: a component is a function
Same input → same UI. Reuse one function with different props (data).
// A React component is "a function that takes data and returns UI".
// We can model that exact idea in plain JS by returning an HTML string.
// 'props' = the inputs a component receives (here: a user's name).
function Welcome(props) {
return "<h1>Welcome, " + props.name + "!</h1>";
}
// Reuse the SAME component with different inputs — that's the whole point.
console.log(Welcome({ name: "Alice" })); // <h1>Welcome, Alice!</h1>
console.log(Welcome({ name: "Bob" })); // <h1>Welcome, Bob!
...3️⃣ JSX — HTML-like Syntax in JavaScript
JSX stands for JavaScript XML. It lets you write HTML-like markup directly inside your JavaScript. The magic is the { curly braces }: anything inside them is treated as a JavaScript expression and its value is dropped into the UI. So <h1>Hello, {name}!</h1> inserts the value of name.
A couple of rules to know up front: a component must return a single root element (wrap siblings in a <div> or an empty <>...</> fragment), and HTML's class attribute becomes className because class is a reserved word in JavaScript.
📄 Read-only worked example — embedding expressions in JSX:
// JSX lets you drop ANY JavaScript value into the UI using { curly braces }.
function Greeting() {
const name = "Alice"; // a normal JS variable
const hour = 9; // 9am
return (
<div>
{/* {name} is replaced by the value of the variable -> Alice */}
<h1>Hello, {name}!</h1>
{/* You can run real expressions inside the braces */}
<p>2 + 2 = {2 + 2}</p> {/* shows: 2 + 2 = 4 */}
<p>{hour < 12 ? "Good morning" : "Good afternoon"}</p> {/* Good morning */}
</div>
);
}
// In HTML you'd write class="..." — in JSX it's className="..."
// because 'class' is a reserved word in JavaScript.4️⃣ The Virtual DOM — Why React Is Fast
Touching the real browser DOM is slow, and doing it constantly is the main cause of sluggish web apps. React's trick is the Virtual DOM: a lightweight copy of your UI kept in memory as plain JavaScript objects. JSX compiles down to calls that build these objects.
When your data changes, React builds a new virtual tree, compares it to the previous one (a process called "diffing"), and then updates only the few real DOM nodes that actually changed — not the whole page. You never write those updates yourself. The runnable demo below shows what a JSX tag actually becomes: a plain object.
🌳 Try It: what JSX compiles to (the Virtual DOM)
See a JSX tag turn into a plain JS object that React can diff.
// JSX is "syntactic sugar". A build tool (Vite) compiles every JSX tag
// into a plain JavaScript function call. Let's SEE what that looks like.
// You WRITE this JSX: <h1 className="title">Hello, Alice!</h1>
// The compiler turns it into a call like React.createElement(...).
// React.createElement returns a plain JS object describing the UI.
function createElement(type, props, ...children) {
return { type, props: props || {}, children };
}
const element = createElement("h1", { clas
...🎯 Your Turn #1: Finish the Component (JSX)
This is real JSX, so it's read-only — fill in the blanks in your head (or in a real Vite project) and check yourself against the ✅ answer in the comments.
// 🎯 YOUR TURN #1 — finish this React component (read-only).
// Fill in each ___ in your head (or in a real Vite project). The correct
// answer is shown on the // ✅ line so you can self-check.
function ProfileCard() {
const username = "sam_dev";
const posts = 42;
return (
___ // 👉 the single wrapper element
<h2>{___}</h2> // 👉 show the username variable
<p>Posts: {___}</p> // 👉 show the posts variable
___ // 👉 close the wrapper element
);
}
// ✅ Expected (one valid answer):
// return (
// <div>
// <h2>{username}</h2>
// <p>Posts: {posts}</p>
// </div>
// );
//
// Reminder: a component must return ONE root element (a <div> or a <>...</>
// fragment) wrapping everything else.5️⃣ Rendering a List (the logic behind it)
React renders lists by mapping over an array of data and returning one element per item. This runnable exercise builds that exact logic in plain JS. Fill in the two blanks, run it, and match the expected output:
🎯 Your Turn #2: build a list with .map() (runnable)
Map data → UI, then join it together — the core of every React list.
// 🎯 YOUR TURN #2 — runnable plain JS (this one really executes!).
// You'll build the same "render data into UI" logic React does, by hand.
// A list of components (here, simple strings) is built by MAPPING over data.
const fruits = ["Apple", "Banana", "Cherry"];
// 1) Replace ___ so each fruit becomes a list-item string.
// 👉 use the item, e.g. "<li>" + fruit + "</li>"
const listItems = fruits.map(function (fruit) {
return ___; // 👉 return "<li>" + fruit + "</li>"
})
...6️⃣ Setting Up a React Project with Vite
The modern way to start a React project is with Vite — a build tool that's extremely fast and gives you instant Hot Module Replacement (your changes appear in the browser the moment you save). The React team now recommends a real build tool like Vite over the older Create React App. You'll need Node.js installed first.
⌨️ Run these commands in your terminal:
# 1) Scaffold a new React project named "my-app"
npm create vite@latest my-app -- --template react
# 2) Move into the folder and install dependencies
cd my-app
npm install
# 3) Start the dev server (opens at http://localhost:5173)
npm run dev📁 What Vite creates (the parts that matter):
my-app/
├── index.html # the single HTML page React mounts into
├── package.json # dependencies & scripts (npm run dev, build)
├── vite.config.js # Vite settings
└── src/
├── main.jsx # entry point — renders <App /> into the page
├── App.jsx # your root component
└── App.css # stylesOpen src/App.jsx, replace its contents with the worked example from section 2, save, and your browser updates instantly. That's the full loop: write a component → save → see it live.
Common Errors (and the fix)
- Forgetting to
returnthe JSX: a function with noreturngives backundefinedand renders nothing. Make sure every component returns its UI — and watch for the classic trap of an opening brace then a newline before(. - Lowercase component names:
<mycard />is treated as a plain HTML tag, not your component. Component names must start with a capital letter —<MyCard />— so React knows it's a component. - "Each child in a list should have a unique key prop": when you
.map()a list to JSX, give each element akey—<li key={id}>. The key helps React's diffing match items between renders. Use a stable id, not the array index where you can. - Adjacent JSX elements must be wrapped: returning two siblings (
<h1/>then<p/>) errors. Wrap them in one<div>or a fragment<>...</>. - Using
classinstead ofclassName: in JSX the attribute isclassName(andforbecomeshtmlFor), becauseclassis a reserved JS word.
Pro Tips
- 💡 One component, one job. If a component is getting big, it's probably several LEGO bricks pretending to be one — split it.
- 💡 Install React Developer Tools (Chrome/Firefox extension) to inspect your component tree, props, and state live in the browser.
- 💡 Name files after the component:
ProfileCard.jsxexportsProfileCard. Future-you will thank you.
📋 Quick Reference — React Basics
| Concept | Syntax | Note |
|---|---|---|
| Function component | function App() { return <h1>Hi</h1>; } | Capital name; must return JSX |
| Embed a value | <p>{name}</p> | { } = a JS expression |
| Single root | <>...</> | Fragment wraps siblings |
| CSS class | <div className="box"> | className, not class |
| List item key | <li key={id}> | Unique key per item |
| Export / import | export default App; | Share a component |
| New project | npm create vite@latest | Then npm install & npm run dev |
Frequently Asked Questions
Q: Is React a language or a framework?
Neither — it's a JavaScript library focused on the UI layer. You still write JavaScript; React gives you components, JSX, and the Virtual DOM. Because it does less than a full framework (like Angular), it's flexible and easy to add to a project.
Q: Do I have to use JSX?
Technically no — JSX compiles to React.createElement() calls you could write by hand — but in practice everyone uses JSX because it's far more readable. It's the standard way to write React.
Q: Why can't I run the JSX examples in the editor here?
JSX isn't valid plain JavaScript — a build tool (Vite/Babel) must compile it first. The editor on this page only runs plain JS, so the real React lives in read-only boxes. Set up Vite (section 6) to run JSX for real.
Q: Vite or Create React App?
Use Vite. It's dramatically faster to start and reload, and it's the current recommendation. Create React App is older and effectively retired.
Mini-Challenge: Reusable Button (runnable)
No blanks this time — just a brief and an outline. Build it, run it, and check your output against the example in the comments. This is the same "function takes props, returns UI" pattern you'll use for every real React component.
🎯 Mini-Challenge: a reusable Button component
Write one function, reuse it with three different labels.
// 🎯 MINI-CHALLENGE: a "render a component with props" demo (runnable JS).
//
// 1. Write a function Button(props) that returns a string:
// "<button>" + props.label + "</button>"
// 2. Call it three times with different labels: "Save", "Cancel", "Delete".
// 3. console.log each result.
//
// ✅ Expected output:
// <button>Save</button>
// <button>Cancel</button>
// <button>Delete</button>
//
// Bonus: build the labels in an array and .map() over them, like React lists.
// your cod
...🎉 Lesson Complete!
- ✅ React is a declarative, component-based UI library — you describe the result, React updates the DOM
- ✅ A component is just a function that returns UI, and components nest and reuse like LEGO bricks
- ✅ JSX is HTML-like syntax in JavaScript;
{ }embeds expressions, and you return one root element - ✅ The Virtual DOM diffs an in-memory tree so only the changed bits of the real page update
- ✅ Start any project with Vite:
npm create vite@latest→npm install→npm run dev - ✅ Next lesson: Components and Props — build reusable components and pass data into them
Sign up for free to track which lessons you've completed and get learning reminders.