← Back to the Build Your Homepage series
⚛️
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 ↗