Introduction to React
Introduction
So far, you’ve built interactive web pages by manually selecting DOM elements, attaching event listeners, and updating content with innerHTML or textContent. This works — but as your apps grow, it becomes harder to manage. What if you need the same card layout on five pages? What if changing one piece of data requires updating three different elements? What if your script.js file grows to 500 lines of querySelector calls?
React solves these problems. It’s a JavaScript library that lets you build user interfaces from small, reusable pieces called components. Instead of imperatively telling the browser how to update the page, you describe what the page should look like, and React handles the rest.
What You’ll Learn
- Why React exists and what problems it solves
- How to set up a React project with Vite
- How to write JSX — HTML-like syntax inside JavaScript
- How to create and compose React components
- How React projects are structured
Why React?
The Problem with Vanilla JavaScript
Consider building a profile card in vanilla JavaScript:
// Vanilla JS — building a card by hand
function createCard(name, role) {
const card = document.createElement("div");
card.classList.add("card");
const h2 = document.createElement("h2");
h2.textContent = name;
const p = document.createElement("p");
p.textContent = role;
card.appendChild(h2);
card.appendChild(p);
return card;
}
// Use it
const container = document.querySelector("#cards");
container.appendChild(createCard("Alice", "Developer"));
container.appendChild(createCard("Bob", "Designer"));This works, but notice the problems:
- Verbose: 12 lines just to create a simple card
- Hard to read: The structure of the card is buried in
createElementandappendChildcalls - No reusability: If you want this card on another page, you copy-paste the entire function
- Difficult to maintain: Change the card structure and you need to update every
createElementcall
The React Solution
Here’s the same card in React:
function Card({ name, role }) {
return (
<div className="card">
<h2>{name}</h2>
<p>{role}</p>
</div>
);
}
// Use it — looks just like HTML!
<Card name="Alice" role="Developer" />
<Card name="Bob" role="Designer" />The React version is:
- Readable: The structure looks like HTML
- Reusable: Use
<Card />anywhere, as many times as you want - Maintainable: Change the card in one place, it updates everywhere
What is React?
- A JavaScript library for building user interfaces, created by Meta (Facebook) in 2013
- The most popular front-end library — used by Meta, Netflix, Airbnb, Discord, and thousands more
- Built on a simple idea: components — small, self-contained pieces of UI that you compose together
Components = Building Blocks
Think of components like Lego blocks. Each component handles one piece of the UI:
Your App
├── Header ← Navigation, logo
├── Main
│ ├── SearchBar ← Input field, search button
│ ├── Card ← Single result
│ ├── Card ← Another result
│ └── Card ← Another result
└── Footer ← Copyright, linksYou build small components and compose them into bigger ones. The App component contains everything, just like your <body> in HTML contains all your page content.
Setting Up React with Vite
What is Vite?
Vite (French for “fast”) is a modern build tool that:
- Creates a ready-to-use React project in seconds
- Compiles JSX into regular JavaScript that browsers understand
- Provides hot module replacement — your browser updates instantly when you save a file
- Replaces the older Create React App (CRA), which is no longer recommended
Creating Your First Project
Open your terminal
Open a terminal in VS Code (Ctrl+` or Terminal → New Terminal).
Create the project
npm create vite@latest my-first-react -- --template reactThis downloads the Vite project creator and sets up a React project in a folder called my-first-react.
Navigate into the project folder
cd my-first-reactInstall dependencies
npm installThis downloads React and other packages into the node_modules/ folder.
Start the development server
npm run devOpen the URL shown in the terminal (usually http://localhost:5173) in your browser. You should see the default Vite + React welcome page.
node -v in your terminal to check. If you don’t have it, download it from nodejs.org.Project Structure
After setup, your project looks like this:
- (dependencies — don’t edit)
- vite.svg
- App.jsx
- App.css
- main.jsx
- index.css
- index.html
- package.json
- vite.config.js
Key files:
| File | Purpose |
|---|---|
src/App.jsx | Your main component — start here |
src/main.jsx | Entry point — renders App into the page |
src/index.css | Global styles |
index.html | Root HTML file with <div id="root"> |
package.json | Project configuration and dependencies |
How It All Connects
index.html → Has <div id="root"></div>
↓
src/main.jsx → Finds #root and renders <App /> into it
↓
src/App.jsx → Your main component (this is where you work)Here’s what main.jsx looks like:
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')).render(<App />)You rarely need to edit main.jsx. Almost all your work happens in App.jsx and the components you create.
Understanding JSX
What is JSX?
JSX (JavaScript XML) is a syntax extension that lets you write HTML-like code inside JavaScript. It’s not HTML — it’s a special syntax that Vite compiles into JavaScript function calls.
// This JSX:
<h1>Hello, World!</h1>
// Gets compiled to this JavaScript:
React.createElement('h1', null, 'Hello, World!')You never need to write React.createElement yourself — JSX handles it for you.
JSX Expressions with Curly Braces
Use curly braces {} to embed any JavaScript expression inside JSX:
function App() {
const name = "CS300";
const year = 2026;
return (
<div>
<h1>Welcome to {name}</h1>
<p>Year: {year}</p>
<p>Sum: {2 + 2}</p>
<p>Uppercase: {name.toUpperCase()}</p>
<p>Random: {Math.floor(Math.random() * 100)}</p>
</div>
);
}`Hello ${name}`), JSX is the same idea. The syntax changes from ${} to {}, but the concept is identical — embedding JavaScript inside markup.JSX vs HTML — Key Differences
JSX looks like HTML but has some important differences:
| HTML | JSX | Why |
|---|---|---|
class="card" | className="card" | class is a reserved keyword in JavaScript |
for="email" | htmlFor="email" | for is a reserved keyword in JavaScript |
<br> | <br /> | All tags must be explicitly closed |
<img src="..."> | <img src="..." /> | Self-closing tags need the / |
style="color: red" | style={{ color: 'red' }} | Styles are JavaScript objects |
onclick="..." | onClick={...} | Event handlers use camelCase |
The two most common ones to remember: className instead of class, and close all tags.
The One Root Rule
A component must return one root element. You can’t return two sibling elements:
// ❌ ERROR — two root elements
function App() {
return (
<h1>Title</h1>
<p>Content</p>
);
}// ✅ Wrap in a div
function App() {
return (
<div>
<h1>Title</h1>
<p>Content</p>
</div>
);
}// ✅ Use a Fragment (no extra DOM node)
function App() {
return (
<>
<h1>Title</h1>
<p>Content</p>
</>
);
}Fragments (<>...</>) let you group elements without adding an extra <div> to the DOM. Use them when you don’t need a wrapper element for styling.
Creating Components
What is a Component?
A React component is a JavaScript function that returns JSX. Three rules:
- PascalCase name —
Greeting, notgreeting(React treats lowercase as HTML elements) - Returns JSX — the function’s return value is what appears on the page
- Exported — so other files can import and use it
Your First Component
// Greeting.jsx
function Greeting() {
return <h2>Hello, welcome to our site!</h2>;
}
export default Greeting;Using a Component
Import it in another file and use it like an HTML tag:
// App.jsx
import Greeting from './Greeting';
function App() {
return (
<div>
<Greeting />
<Greeting />
<Greeting />
</div>
);
}
export default App;Three <Greeting /> tags = three greetings on the page. Write the component once, use it as many times as you want.
<Greeting /> renders your component. <greeting /> would look for an HTML element called greeting (which doesn’t exist).Component with Variables
Components can contain variables and logic, just like any JavaScript function:
// ProfileCard.jsx
function ProfileCard() {
const name = "Jane Smith";
const role = "Web Developer";
const bio = "I love building things for the web!";
const yearStarted = 2020;
const experience = 2026 - yearStarted;
return (
<div className="profile-card">
<h2>{name}</h2>
<p className="role">{role}</p>
<p>{bio}</p>
<p>{experience} years of experience</p>
</div>
);
}
export default ProfileCard;Composing Components
The real power of React is composition — building complex UIs from simple components.
Building an App from Components
// Header.jsx
function Header() {
return (
<header>
<h1>My React App</h1>
<nav>
<a href="#home">Home</a>
<a href="#about">About</a>
<a href="#contact">Contact</a>
</nav>
</header>
);
}
export default Header;// Footer.jsx
function Footer() {
return (
<footer>
<p>© 2026 CS300 Class</p>
</footer>
);
}
export default Footer;// App.jsx — composing everything together
import Header from './Header';
import Footer from './Footer';
import ProfileCard from './ProfileCard';
function App() {
return (
<div>
<Header />
<main>
<h2>Team Members</h2>
<ProfileCard />
<ProfileCard />
<ProfileCard />
</main>
<Footer />
</div>
);
}
export default App;The Component Tree
Every React app forms a tree of components:
App
├── Header
│ └── nav (HTML)
├── main (HTML)
│ ├── ProfileCard
│ ├── ProfileCard
│ └── ProfileCard
└── FooterApp is the root component — it contains everything. Each component manages its own piece of the UI.
Benefits of Composition
- Reusability: Use
<ProfileCard />on any page - Isolation: Changing
Headerdoesn’t affectFooter - Readability:
App.jsxreads like a table of contents - Teamwork: Different developers can work on different components
Common Patterns
Cleaning Up the Default Vite Project
When you create a new Vite project, it comes with demo content. Here’s how to start fresh:
Clear App.jsx
Replace the default content with a simple component:
function App() {
return (
<div>
<h1>Hello React!</h1>
</div>
);
}
export default App;Clear App.css
Delete all the default styles or replace with your own.
Clear index.css
Keep only basic resets if desired:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: system-ui, sans-serif;
line-height: 1.6;
padding: 20px;
}Delete unused files
Remove src/assets/react.svg and any other demo files you don’t need.
Creating a New Component
Follow this pattern every time you create a component:
// 1. Create a new file with PascalCase name: ComponentName.jsx
// 2. Write the function
function ComponentName() {
return (
<div>
{/* Your JSX here */}
</div>
);
}
// 3. Export it
export default ComponentName;
// 4. Import it where you need it:
// import ComponentName from './ComponentName';Adding CSS to a Component
Create a CSS file with the same name and import it:
/* ProfileCard.css */
.profile-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
max-width: 300px;
}
.profile-card h2 {
margin-bottom: 8px;
color: #333;
}
.profile-card .role {
color: #666;
font-style: italic;
}// ProfileCard.jsx
import './ProfileCard.css';
function ProfileCard() {
return (
<div className="profile-card">
<h2>Jane Smith</h2>
<p className="role">Web Developer</p>
<p>I love building things for the web!</p>
</div>
);
}
export default ProfileCard;Troubleshooting & Common Mistakes
I get ‘React is not defined’ or JSX errors
.jsx extension (not .js). Vite uses the extension to know it should process JSX. If you’re using an older setup, you may need to import React from 'react' at the top.My component doesn’t show up
Check these things in order:
- Did you export it? The component file needs
export default ComponentName; - Did you import it? The file using it needs
import ComponentName from './ComponentName'; - Did you use it in JSX? Add
<ComponentName />in your return statement - Is it PascalCase?
<greeting />won’t work — use<Greeting /> - Is the file path correct? Check for typos in the import path
I see ‘Adjacent JSX elements must be wrapped in an enclosing tag’
Your component is returning multiple root elements. Wrap them in a <div> or a Fragment <>...</>:
// ❌ Error
return (
<h1>Title</h1>
<p>Content</p>
)
// ✅ Fix
return (
<>
<h1>Title</h1>
<p>Content</p>
</>
)I used ‘class’ instead of ‘className’ and got a warning
In JSX, HTML’s class attribute becomes className because class is a reserved word in JavaScript. Same for for → htmlFor.
// ❌ Warning
<div class="card">
// ✅ Correct
<div className="card">npm run dev shows an error or nothing loads
Common fixes:
- Make sure you ran
npm installfirst - Check that you’re in the project folder (
cd my-first-react) - Make sure Node.js is installed (
node -vshould show a version) - Try deleting
node_modules/and runningnpm installagain - Check that port 5173 isn’t already in use by another dev server
My changes don’t show up in the browser
- Make sure you saved the file (Ctrl+S / Cmd+S)
- Check the terminal — if there’s a compilation error, fix it and save again
- Try a hard refresh in the browser (Ctrl+Shift+R / Cmd+Shift+R)
- Make sure
npm run devis still running in your terminal
Key Takeaways
- React is a JavaScript library for building UIs from reusable components
- Components are functions that return JSX — PascalCase names, one root element, exported
- Vite sets up your project:
npm create vite@latest→npm install→npm run dev - JSX looks like HTML but lives in JavaScript — use
{}for expressions,classNameinstead ofclass - Composition = building big components from small ones, like Lego blocks
- React doesn’t replace JavaScript — it organizes the DOM manipulation, events, and data you already know