⚛️ Introduction to React
Welcome to the world of React! You've mastered TypeScript - now it's time to combine it with one of the most powerful tools for building modern web applications. React has revolutionized how we think about user interfaces, making it easier to build complex, interactive applications that are maintainable and performant. Whether you're building a simple todo app or the next Facebook (React's birthplace!), the concepts you'll learn here are fundamental. Let's dive in! 🚀
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Explain what React is and why it's popular for building user interfaces
- Understand the core concepts: components, declarative programming, and the virtual DOM
- Recognize the difference between React and vanilla JavaScript approaches
- Set up a basic React development environment
- Create your first React component with TypeScript
- Understand how React fits into modern web development
Estimated Time: 60-75 minutes
Project: Set up your development environment and create your first "Hello World" React component
📑 In This Lesson
🤔 What is React?
React is a JavaScript library for building user interfaces, created and maintained by Meta (formerly Facebook). It was released as open-source in 2013 and has since become one of the most popular tools for web development.
📖 Definition
React: A declarative, component-based JavaScript library for building user interfaces. It lets you compose complex UIs from small, isolated pieces of code called "components."
A Brief History
React was born at Facebook in 2011 when Jordan Walke, a software engineer, created FaxJS (the early prototype). The problem they were trying to solve was simple but challenging: how do you build a complex, interactive UI that stays in sync with constantly changing data?
Think about Facebook's news feed - new posts appear, likes update in real-time, comments load dynamically. Traditional approaches required a lot of manual DOM manipulation, which became messy and error-prone as applications grew. React offered a better way.
React is a Library, Not a Framework
It's important to understand that React is technically a library, not a full framework like Angular or Vue. This distinction matters:
| Aspect | Library (React) | Framework (Angular) |
|---|---|---|
| Scope | Focused on UI/View layer | Complete solution (routing, state, forms, etc.) |
| Flexibility | Choose your own tools | Opinionated, prescribed way |
| Learning Curve | Learn as you grow | Everything upfront |
| Size | Lightweight (~40KB) | Heavier (~500KB+) |
💡 Real-World Analogy
Think of React like LEGO blocks. React gives you the blocks (components) and the rules for connecting them, but you decide what to build and what other pieces you need. A framework is more like a model kit - everything's included and there's a specific way to put it together.
Who Uses React?
React powers some of the world's most popular applications:
- Facebook - Where it all began (news feed, groups, marketplace)
- Instagram - The entire web interface
- Netflix - The streaming interface you know and love
- Airbnb - Search, booking, and host interfaces
- WhatsApp Web - The browser version of the messaging app
- Dropbox - File management and collaboration tools
- Discord - Real-time chat and community features
These aren't small projects - we're talking about applications serving billions of users! If React can handle that scale, it can definitely handle your projects. 💪
💎 Why React?
With so many options for building web applications, why has React become so dominant? Let's explore the key reasons developers love React.
1. Component-Based Architecture
React lets you break your UI into independent, reusable pieces called components. Instead of one massive file with all your HTML, CSS, and JavaScript mixed together, you create small, focused components that do one thing well.
✅ The LEGO Principle
Just like building with LEGO, you create small pieces that snap together to form something bigger. Need a button? Build a Button component. Need ten buttons? Use that component ten times. Need to change all your buttons? Update one component, and they all change. This is the power of reusability!
2. Declarative Programming
React uses a declarative approach - you describe what you want the UI to look like, not how to change it. React handles the "how" for you.
// Imperative (vanilla JavaScript) - HOW to do it
const button = document.createElement('button');
button.textContent = 'Click me';
button.addEventListener('click', () => {
const message = document.getElementById('message');
message.textContent = 'Button clicked!';
});
document.body.appendChild(button);
// Declarative (React) - WHAT you want
function MyButton() {
const [message, setMessage] = useState('');
return (
<>
<button onClick={() => setMessage('Button clicked!')}>
Click me
</button>
<p>{message}</p>
</>
);
}
Notice how the React version is easier to read and understand? You can see the structure of your UI at a glance. This is declarative programming in action!
3. Virtual DOM = Fast Updates
Directly manipulating the browser's DOM (Document Object Model) is slow. React uses a "virtual DOM" - a lightweight copy of the actual DOM in JavaScript. When data changes, React:
- Updates the virtual DOM (fast)
- Compares it with the previous virtual DOM (diffing)
- Calculates the minimum changes needed (reconciliation)
- Updates only what changed in the real DOM (efficient)
🎨 Interactive: Virtual DOM in Action
Watch how React's Virtual DOM efficiently updates only what changed. Click "Update Data" to see the diffing process:
Click "Update Data" to see Virtual DOM diffing
💡 Real-World Analogy
Imagine you're editing a document. You could rewrite the entire document every time you make a change (slow), or you could just update the specific words that changed (fast). React's virtual DOM is like having a smart editor that knows exactly what changed and only rewrites those parts.
4. Rich Ecosystem
React has a massive ecosystem of tools, libraries, and resources:
- React Router - Navigation and routing
- Redux / Zustand - State management
- Next.js - Full-featured React framework with server-side rendering
- React Testing Library - Testing utilities
- Material-UI, Chakra UI, shadcn/ui - Component libraries
- React Native - Build mobile apps with React
5. Strong Community & Job Market
React has one of the largest developer communities in the world. This means:
- Tons of tutorials, courses, and learning resources
- Active forums and communities (Stack Overflow, Reddit, Discord)
- Regular updates and improvements
- Abundant job opportunities - React developers are in high demand!
6. Learn Once, Write Anywhere
The skills you learn with React transfer to multiple platforms:
- Web apps - With React DOM
- Mobile apps - With React Native (iOS & Android)
- Desktop apps - With Electron
- VR experiences - With React 360
| Benefit | What It Means For You |
|---|---|
| Component Reusability | Write less code, build faster |
| Declarative UI | Code that's easier to read and maintain |
| Virtual DOM | Fast, responsive applications |
| Rich Ecosystem | Solutions already exist for common problems |
| Strong Community | Help when you need it, jobs when you're ready |
| Cross-Platform | One skillset, multiple platforms |
🎯 Core Concepts
Before we start coding, let's understand the fundamental concepts that make React work. These are the building blocks of every React application.
Components: The Heart of React
Everything in React is a component. A component is a self-contained piece of UI that can be reused throughout your application. Components can be as simple as a button or as complex as an entire page.
📖 Definition
Component: A reusable, self-contained piece of UI that encapsulates its own structure (HTML), style (CSS), and behavior (JavaScript). Think of it as a custom HTML element that you create.
There are two types of components:
1. Function Components (What We'll Use)
// A simple function component
function Welcome() {
return <h1>Hello, World!</h1>;
}
// Function component with TypeScript and props
interface GreetingProps {
name: string;
}
function Greeting({ name }: GreetingProps) {
return <h1>Hello, {name}!</h1>;
}
2. Class Components (Legacy, But You'll See Them)
// Class component (older style)
class Welcome extends React.Component {
render() {
return <h1>Hello, World!</h1>;
}
}
✅ Modern React = Function Components
We'll focus on function components throughout this course. They're simpler, more concise, and the React team recommends them for all new code. Class components still exist in legacy codebases, so it's good to recognize them, but you won't need to write them.
JSX/TSX: HTML in JavaScript
JSX (JavaScript XML) is a syntax extension that lets you write HTML-like code in your JavaScript files. When you use TypeScript with React, it's called TSX.
// This looks like HTML, but it's JSX/TSX
const element = (
<div className="welcome">
<h1>Hello, World!</h1>
<p>Welcome to React with TypeScript!</p>
</div>
);
Under the hood, JSX gets transformed into regular JavaScript function calls:
// The JSX above becomes something like this:
const element = React.createElement(
'div',
{ className: 'welcome' },
React.createElement('h1', null, 'Hello, World!'),
React.createElement('p', null, 'Welcome to React with TypeScript!')
);
JSX makes your code much more readable! You'll learn all about JSX/TSX in the next lesson.
Props: Passing Data to Components
Props (short for "properties") are how you pass data from a parent component to a child component. They're like function arguments, but for components.
// Define the props interface
interface UserCardProps {
name: string;
age: number;
email: string;
}
// Component that receives props
function UserCard({ name, age, email }: UserCardProps) {
return (
<div className="user-card">
<h2>{name}</h2>
<p>Age: {age}</p>
<p>Email: {email}</p>
</div>
);
}
// Using the component with props
function App() {
return (
<div>
<UserCard name="Alice" age={30} email="alice@example.com" />
<UserCard name="Bob" age={25} email="bob@example.com" />
</div>
);
}
⚠️ Important: Props Are Read-Only
A component must never modify its own props. Props flow one way - from parent to child. Think of them as function parameters: you can read them and use them, but you can't change them inside the function.
State: Data That Changes
While props are read-only data passed from parents, state is data that belongs to a component and can change over time. When state changes, React re-renders the component to reflect the new data.
import { useState } from 'react';
function Counter() {
// useState returns [current value, function to update it]
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
🎨 Interactive: Props vs State Comparison
See the difference between Props (read-only, from parent) and State (internal, changeable):
The Component Tree
React applications are structured as a tree of components. At the top is your root component (usually called App), and it contains child components, which may contain their own children, and so on.
🎨 Interactive: Component Tree Explorer
Click on components to see how they relate to each other. Notice how data flows from parent to child!
This tree structure makes it easy to reason about your application and manage data flow.
⚖️ React vs Vanilla JavaScript
To really appreciate what React does for us, let's compare building the same feature with and without React. We'll create a simple counter that increments when you click a button.
Vanilla JavaScript Approach
<!-- HTML -->
<div id="app">
<p>Count: <span id="count">0</span></p>
<button id="increment">Increment</button>
<button id="decrement">Decrement</button>
<button id="reset">Reset</button>
</div>
<script>
// JavaScript
let count = 0;
const countElement = document.getElementById('count');
const incrementBtn = document.getElementById('increment');
const decrementBtn = document.getElementById('decrement');
const resetBtn = document.getElementById('reset');
function updateDisplay() {
countElement.textContent = count;
// Maybe update button states based on count
// Maybe update styles
// Getting complex already!
}
incrementBtn.addEventListener('click', () => {
count++;
updateDisplay();
});
decrementBtn.addEventListener('click', () => {
count--;
updateDisplay();
});
resetBtn.addEventListener('click', () => {
count = 0;
updateDisplay();
});
</script>
React Approach
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
<button onClick={() => setCount(count - 1)}>
Decrement
</button>
<button onClick={() => setCount(0)}>
Reset
</button>
</div>
);
}
💡 What's The Difference?
Vanilla JavaScript: You manually find elements, attach event listeners, and update the DOM. You're responsible for keeping the UI in sync with your data.
React: You describe what the UI should look like based on the current state. When state changes, React automatically updates the UI. You never touch the DOM directly!
Let's Add More Features...
Now imagine we want to add:
- Display the count in multiple places
- Show a message when count is positive/negative
- Disable buttons based on count value
- Add a count history
- Animate the changes
With vanilla JavaScript: You'd need to manually update every element, manage multiple event listeners, keep track of which elements need updating, handle edge cases... It gets messy fast! 😰
With React: You just update the state, and React handles updating everything else. The complexity doesn't grow as dramatically. 🎉
| Aspect | Vanilla JavaScript | React |
|---|---|---|
| DOM Updates | Manual, imperative | Automatic, declarative |
| Code Organization | HTML, CSS, JS separate | Organized by component |
| Reusability | Limited, requires careful planning | Built-in component system |
| Complexity Growth | Gets messy quickly | Stays manageable longer |
| Performance | You optimize manually | Virtual DOM optimizes for you |
| Learning Curve | Easier to start | Steeper initial curve |
✅ When to Use Each
Vanilla JavaScript: Small scripts, simple interactions, when you don't need a build step, learning fundamentals.
React: Complex UIs, applications with lots of state, when you need reusable components, team projects, when performance matters.
🛠️ Setting Up Your Environment
Let's get your development environment ready for React! We'll use Vite - a modern, fast build tool that's perfect for React development.
Prerequisites
Before we start, make sure you have:
- Node.js (version 18 or higher) - Download here
- npm or yarn (comes with Node.js)
- A code editor - We recommend VS Code
Option 1: Create a New React App with Vite (Recommended)
Vite is lightning fast and provides a great developer experience. Let's create our first React + TypeScript project!
# Create a new project
npm create vite@latest my-react-app -- --template react-ts
# Navigate into the project
cd my-react-app
# Install dependencies
npm install
# Start the development server
npm run dev
After running npm run dev, you'll see something like:
Output:
VITE v5.0.0 ready in 500 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help
Open http://localhost:5173/ in your browser, and you'll see your React app running! 🎉
Understanding the Project Structure
Let's explore what Vite created for us:
my-react-app/
├── node_modules/ # Dependencies (don't touch this!)
├── public/ # Static assets (images, fonts, etc.)
├── src/ # Your React code lives here
│ ├── App.tsx # Main App component
│ ├── App.css # Styles for App
│ ├── main.tsx # Entry point
│ └── index.css # Global styles
├── index.html # HTML template
├── package.json # Project config and dependencies
├── tsconfig.json # TypeScript configuration
└── vite.config.ts # Vite configuration
Key Files Explained
index.html - The Entry Point
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Notice the <div id="root"></div>? This is where your entire React application will be mounted!
src/main.tsx - The JavaScript Entry Point
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
// This is where React takes over!
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)
This file:
- Imports React and ReactDOM
- Imports your App component
- Finds the
rootdiv in index.html - Renders your App component inside it
💡 What is StrictMode?
React.StrictMode is a tool that highlights potential problems in your application during development. It doesn't render anything visible - it just adds extra checks and warnings. Keep it! It helps you write better React code.
Option 2: Online Playground (For Quick Experiments)
Don't want to set up a local environment yet? Try these online tools:
- CodeSandbox - Full-featured online IDE
- StackBlitz - VS Code in the browser
- PlayCode - Simple and fast
⚠️ Development vs Production
The development server (npm run dev) includes helpful tools like hot reloading and detailed error messages. When you're ready to deploy, you'll run npm run build to create an optimized production version. We'll cover deployment in Module 10!
Recommended VS Code Extensions
If you're using VS Code, install these extensions for a better experience:
- ES7+ React/Redux/React-Native snippets - Code snippets
- ESLint - Code quality checks
- Prettier - Code formatting
- Auto Rename Tag - Rename paired JSX tags
🎨 Your First React Component
Now that your environment is set up, let's create your first component from scratch! We'll build a simple greeting card component.
Step 1: Create a New Component File
In your src folder, create a new file called Greeting.tsx:
// src/Greeting.tsx
// Define the props interface
interface GreetingProps {
name: string;
age?: number; // Optional prop
}
// Create the component
function Greeting({ name, age }: GreetingProps) {
return (
<div className="greeting-card">
<h2>Hello, {name}!</h2>
{age && <p>You are {age} years old.</p>}
<p>Welcome to React with TypeScript!</p>
</div>
);
}
// Export the component so others can use it
export default Greeting;
Let's break down what's happening here:
- Interface: We define the shape of our props with TypeScript
- Function: Our component is a regular function that returns JSX
- JSX: We write HTML-like syntax inside JavaScript
- Curly Braces:
{name}lets us embed JavaScript expressions - Conditional:
{age && ...}only shows the age if it's provided - Export: Makes the component available to import elsewhere
Step 2: Add Some Styles
Create a CSS file Greeting.css:
/* src/Greeting.css */
.greeting-card {
padding: 2rem;
border: 2px solid #667eea;
border-radius: 8px;
background: linear-gradient(135deg, #667eea15 0%, #764ba215 100%);
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
max-width: 400px;
margin: 2rem auto;
}
.greeting-card h2 {
color: #667eea;
margin-bottom: 1rem;
}
.greeting-card p {
color: #555;
line-height: 1.6;
}
Now import the CSS in your component:
// src/Greeting.tsx
import './Greeting.css'; // Add this line at the top
interface GreetingProps {
name: string;
age?: number;
}
function Greeting({ name, age }: GreetingProps) {
// ... rest of the component
}
Step 3: Use Your Component
Open src/App.tsx and use your new component:
// src/App.tsx
import Greeting from './Greeting'
import './App.css'
function App() {
return (
<div className="App">
<h1>My First React App</h1>
<Greeting name="Alice" age={30} />
<Greeting name="Bob" />
<Greeting name="Charlie" age={25} />
</div>
)
}
export default App
Save all files, and your browser will automatically reload (hot reload) showing your greeting cards! 🎉
✅ Component Best Practices
- One component per file - Makes code easier to find and maintain
- PascalCase names -
Greeting, notgreeting - TypeScript interfaces - Always define prop types
- Co-located styles - Keep CSS files next to components
- Default exports - For the main component in a file
Adding Interactivity
Let's make our component interactive by adding a button:
// src/Greeting.tsx
import { useState } from 'react'; // Import useState
import './Greeting.css';
interface GreetingProps {
name: string;
age?: number;
}
function Greeting({ name, age }: GreetingProps) {
// Add state for click count
const [clicks, setClicks] = useState(0);
return (
<div className="greeting-card">
<h2>Hello, {name}!</h2>
{age && <p>You are {age} years old.</p>}
<p>Welcome to React with TypeScript!</p>
<button onClick={() => setClicks(clicks + 1)}>
Clicked {clicks} times
</button>
</div>
);
}
export default Greeting;
Now each greeting card has its own independent click counter! This demonstrates component state - each instance of the Greeting component maintains its own separate state. 🎯
⚙️ How React Works Under the Hood
Now that you've created your first component, let's understand what React is actually doing behind the scenes. Understanding this will help you write better React code!
The Component Lifecycle
Every React component goes through a lifecycle with three main phases:
- Mounting - Component is created and inserted into the DOM
- Updating - Component re-renders when props or state change
- Unmounting - Component is removed from the DOM
🎨 Interactive: Component Lifecycle Simulator
Simulate a component's lifecycle and see which phase it's in:
The Rendering Process
When a component renders, here's what happens:
- React calls your component function - Gets the JSX you return
- Converts JSX to React elements - JavaScript objects describing the UI
- Creates/updates the virtual DOM - A lightweight copy of the real DOM
- Compares with previous virtual DOM (reconciliation)
- Calculates minimal changes needed (diffing algorithm)
- Updates only changed parts of the real DOM (commit phase)
// When you write this:
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
// React creates this (simplified):
{
type: 'button',
props: {
onClick: () => setCount(count + 1),
children: count
}
}
When Does React Re-render?
React re-renders a component when:
- State changes - You call a state setter function
- Props change - Parent passes new props
- Parent re-renders - Child components re-render too
- Context changes - Using React Context (we'll learn this later)
⚠️ Common Misconception
Re-rendering doesn't mean the entire DOM is recreated! React is smart - it only updates the parts that actually changed. This is why React is so fast.
One-Way Data Flow
React enforces a one-way data flow (also called "unidirectional data flow"):
- Data flows down from parent to child via props
- Events flow up from child to parent via callbacks
- This makes data changes predictable and easier to debug
// Parent passes data down and receives events up
function Parent() {
const [message, setMessage] = useState('');
// Event handler passed as prop
const handleChildClick = (childData: string) => {
setMessage(childData);
};
return (
<div>
<p>Message from child: {message}</p>
{/* Data flows down via props */}
<Child onButtonClick={handleChildClick} />
</div>
);
}
function Child({ onButtonClick }: { onButtonClick: (data: string) => void }) {
return (
<button onClick={() => onButtonClick('Hello from child!')}>
Click me
</button>
);
}
React Fiber Architecture
Under the hood, React uses an architecture called "Fiber" (introduced in React 16). You don't need to know the details, but here's what it does:
- Breaks rendering into chunks - Can pause and resume work
- Prioritizes updates - User interactions get priority over background updates
- Concurrent rendering - Can prepare multiple versions of the UI
This is why React stays responsive even when rendering large component trees! 🚀
✅ Key Takeaway
You don't need to understand all the internals to use React effectively! Just remember: React is optimized for performance out of the box. Write clean component code, and React handles the rest.
🏋️ Hands-on Practice
🏋️ Exercise 1: Create a Profile Card Component
Objective: Build a reusable profile card component with TypeScript.
Requirements:
- Create a component called
ProfileCard - Accept props:
name,title,email,imageUrl(optional) - Display the information in a styled card
- If no image is provided, show placeholder initials
- Add a "Contact" button that shows the email when clicked
Starter Code:
// src/ProfileCard.tsx
import { useState } from 'react';
import './ProfileCard.css';
interface ProfileCardProps {
// TODO: Define your props interface
}
function ProfileCard(/* TODO: Add props */) {
// TODO: Add state for showing/hiding email
return (
<div className="profile-card">
{/* TODO: Implement your component */}
</div>
);
}
export default ProfileCard;
💡 Hint 1
Use a state variable to track whether the email should be visible. The button's onClick handler can toggle this state.
💡 Hint 2
To get initials, you can split the name by spaces and take the first letter of each word: name.split(' ').map(n => n[0]).join('')
✅ Solution
// src/ProfileCard.tsx
import { useState } from 'react';
import './ProfileCard.css';
interface ProfileCardProps {
name: string;
title: string;
email: string;
imageUrl?: string;
}
function ProfileCard({ name, title, email, imageUrl }: ProfileCardProps) {
const [showEmail, setShowEmail] = useState(false);
// Get initials if no image
const initials = name
.split(' ')
.map(n => n[0])
.join('')
.toUpperCase();
return (
<div className="profile-card">
<div className="profile-image">
{imageUrl ? (
<img src={imageUrl} alt={name} />
) : (
<div className="initials">{initials}</div>
)}
</div>
<h3>{name}</h3>
<p className="title">{title}</p>
{showEmail && (
<p className="email">{email}</p>
)}
<button onClick={() => setShowEmail(!showEmail)}>
{showEmail ? 'Hide' : 'Show'} Contact
</button>
</div>
);
}
export default ProfileCard;
/* src/ProfileCard.css */
.profile-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 1.5rem;
max-width: 300px;
text-align: center;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.profile-image {
width: 100px;
height: 100px;
margin: 0 auto 1rem;
border-radius: 50%;
overflow: hidden;
}
.profile-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.initials {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #667eea;
color: white;
font-size: 2rem;
font-weight: bold;
}
.profile-card h3 {
margin: 0.5rem 0;
color: #333;
}
.title {
color: #666;
margin: 0.5rem 0;
}
.email {
color: #667eea;
margin: 1rem 0;
}
.profile-card button {
background: #667eea;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 4px;
cursor: pointer;
}
.profile-card button:hover {
background: #5568d3;
}
🏋️ Exercise 2: Build a Toggle Switch Component
Objective: Create a reusable toggle switch with labels and callbacks.
Requirements:
- Component accepts:
label,defaultChecked(optional),onChangecallback - Toggle between on/off states
- Call the onChange callback when toggled
- Style it to look like a modern toggle switch
💡 Hint
Use a checkbox input with custom styling. The checked attribute controls the state, and onChange updates it.
✅ Solution
// src/ToggleSwitch.tsx
import { useState } from 'react';
import './ToggleSwitch.css';
interface ToggleSwitchProps {
label: string;
defaultChecked?: boolean;
onChange?: (checked: boolean) => void;
}
function ToggleSwitch({ label, defaultChecked = false, onChange }: ToggleSwitchProps) {
const [checked, setChecked] = useState(defaultChecked);
const handleChange = () => {
const newValue = !checked;
setChecked(newValue);
if (onChange) {
onChange(newValue);
}
};
return (
<div className="toggle-switch">
<label>
<input
type="checkbox"
checked={checked}
onChange={handleChange}
/>
<span className="slider"></span>
<span className="label">{label}</span>
</label>
</div>
);
}
export default ToggleSwitch;
🎯 Quick Quiz
Question 1: What is React primarily used for?
Question 2: What makes React fast when updating the UI?
Question 3: How do you pass data from a parent component to a child component?
🏆 Best Practices
✅ Do's
- Keep components small and focused - Each component should do one thing well. If it's getting large, break it into smaller components.
- Use TypeScript interfaces for props - Type safety prevents bugs and makes your code self-documenting.
- Name components with PascalCase -
MyComponent, notmyComponentormy-component. - Co-locate related files - Keep component, styles, and tests together in the same folder.
- Use meaningful prop names -
userNameis better thandataorx. - Extract reusable components - If you're copying code, it should probably be a component.
- Follow the single responsibility principle - One component, one job.
❌ Don'ts
- Don't mutate props - Props are read-only. Never modify them directly.
- Don't modify state directly - Always use the setter function from useState.
- Don't nest components inside other components - Define components at the top level of your file.
- Don't forget to add keys to list items - React needs keys to efficiently update lists (we'll cover this soon).
- Don't use indexes as keys - When mapping arrays, use stable IDs, not array indexes.
- Don't create components with too many props - If you have 10+ props, consider splitting the component.
💡 Pro Tips
- Use React DevTools - Install the browser extension to inspect your component tree and debug issues.
- Destructure props in the parameter -
({ name, age })instead of(props)makes your code cleaner. - Use optional chaining -
user?.namesafely accesses properties that might not exist. - Learn the ESLint rules - React has helpful ESLint plugins that catch common mistakes.
- Start with function components - Modern React uses function components almost exclusively.
- Think in components - Before coding, sketch out your UI and identify the component boundaries.
Component Organization
A well-organized component file follows this structure:
// 1. Imports (libraries first, then components, then styles)
import { useState } from 'react';
import SomeComponent from './SomeComponent';
import './MyComponent.css';
// 2. Types and interfaces
interface MyComponentProps {
title: string;
count: number;
}
// 3. Component definition
function MyComponent({ title, count }: MyComponentProps) {
// 4. Hooks (useState, useEffect, etc.)
const [active, setActive] = useState(false);
// 5. Event handlers
const handleClick = () => {
setActive(!active);
};
// 6. Helper functions (if any)
const formatTitle = (text: string) => {
return text.toUpperCase();
};
// 7. Render logic
return (
<div>
<h2>{formatTitle(title)}</h2>
<p>Count: {count}</p>
<button onClick={handleClick}>
{active ? 'Active' : 'Inactive'}
</button>
</div>
);
}
// 8. Export
export default MyComponent;
📝 Summary
🎉 Congratulations!
You've taken your first steps into the React ecosystem! Here's what you've learned:
- What React is - A component-based library for building UIs
- Why React matters - Declarative, fast, and widely adopted
- Core concepts - Components, JSX, props, state, and one-way data flow
- Virtual DOM - How React efficiently updates the UI
- Setting up - Creating a React project with Vite and TypeScript
- Building components - Your first function components with TypeScript
- Component lifecycle - Mounting, updating, and unmounting
- Best practices - Writing clean, maintainable React code
🎯 Key Takeaways
- React lets you build UIs from composable components
- Components are just JavaScript functions that return JSX
- TypeScript adds type safety to your React code
- Props pass data down, events flow up
- State lets components remember and react to changes
- The virtual DOM makes React fast and efficient
📚 Additional Resources
- Official React Documentation - The best place to learn
- Thinking in React - Essential guide to the React mindset
- React TypeScript Cheatsheet - Quick reference
- Vite Documentation - Learn about your build tool
🚀 What's Next?
In the next lesson, we'll dive deep into JSX and TSX. You'll learn:
- How JSX/TSX works in detail
- Embedding expressions and using JavaScript in JSX
- Conditional rendering techniques
- Rendering lists and handling keys
- JSX gotchas and best practices
Get ready to master the syntax that makes React so expressive and powerful! 💪
🎉 You're on Your Way!
You've learned the fundamentals of React and created your first components. The journey from here gets even more exciting as we build on these concepts to create amazing applications!
See you in the next lesson! ⚛️