⚛️
EPISODE 01
JSX · props · function components · useState
Components & useState
Compose UI from reusable components. Pass data with props, manage local state with useState, and re-render automatically when state changes.
ReactcomponentspropsuseStateJSX
Duration
⏱ About 2 hours
Level
📊 Intermediate
Prerequisite
🎯 Lesson 5 + JS basics
OUTCOME
A small React app with stateful, prop-driven components
What you'll learn
- 1Write function components with JSX
- 2Pass data with typed props
- 3Manage local state with useState
- 4Lift state up when two siblings need it
1. Function Components
tsx
type CardProps = { title: string; description: string };
export default function Card({ title, description }: CardProps) {
return (
<div className="rounded-xl border p-4">
<h2 className="text-lg font-bold">{title}</h2>
<p className="text-gray-600">{description}</p>
</div>
);
}2. JSX Rules
- className instead of class
- Self-closing tags need a closing slash (<br />)
- JS expressions in { } — including conditionals and array.map
- Return one root element (use <>...</> fragment when needed)
tsx
{count > 0 && <p>Items: {count}</p>}
{items.map(i => <li key={i.id}>{i.name}</li>)}
<>multiple <strong>elements</strong></>3. useState
tsx
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>Count: {count}</button>
);
}⚠️
Never mutate state. setCount(count + 1) is correct; count = count + 1 silently breaks rerendering.
4. Lifting State Up
When two sibling components need the same state, move it up to their common parent and pass it down via props.
tsx
function App() {
const [filter, setFilter] = useState("");
return (
<>
<SearchBar value={filter} onChange={setFilter} />
<ItemList filter={filter} />
</>
);
}Example code / lecture materials
All lecture materials and example code are openly available on GitHub.
View on GitHub ↗