REACT & NEXT.JS / 1. COMPONENTS & JSX

Components & JSX

The building blocks — everything in React is a component


EXPLANATION

A component is a function that returns JSX (JavaScript XML — HTML-like syntax that compiles to React.createElement calls).

Rules:
• Component names MUST start with uppercase (lowercase = HTML element)
• Must return a single root element (use <> fragment if needed)
• JSX expressions go inside {}

Props: data passed from parent to child. Read-only — never mutate props.
Children: special prop — content between component tags.

Component composition: the React way of reusing UI. Instead of inheritance, you compose small components into larger ones.

Key JSX gotchas:
• class → className (class is reserved in JS)
• for → htmlFor (same reason)
• style takes an object: style={{ color: "red" }}
• All tags must be closed: <img /> not <img>
• Conditional rendering: {condition && <Component />} or ternary
• List rendering: always provide a unique key prop

DIAGRAM

Component tree:

  <App>
    <Navbar logo="deepdocs" />
    <main>
      <Sidebar>
        <NavItem href="/rag">RAG & LLMs</NavItem>
        <NavItem href="/ml">Machine Learning</NavItem>
      </Sidebar>
      <Article>
        <h1>{title}</h1>
        <CodeBlock code={code} lang="python" />
      </Article>
    </main>
  </App>

  Data flows DOWN (props), events bubble UP (callbacks)
  Parent → Child: props
  Child → Parent: callback functions passed as props

CODE

TSX
1// ── Basic component ─────────────────────────────────────────────
2type ButtonProps = {
3 label: string;
4 onClick: () => void;
5 variant?: "primary" | "ghost"; // optional prop
6 disabled?: boolean;
7};
8
9export function Button({ label, onClick, variant = "primary", disabled = false }: ButtonProps) {
10 return (
11 <button
12 onClick={onClick}
13 disabled={disabled}
14 className={`btn btn-${variant} ${disabled ? "opacity-50" : ""}`}
15 >
16 {label}
17 </button>
18 );
19}
20
21// ── Children prop ────────────────────────────────────────────────
22type CardProps = {
23 title: string;
24 children: React.ReactNode; // anything renderable
25};
26
27export function Card({ title, children }: CardProps) {
28 return (
29 <div className="rounded-lg border p-4">
30 <h2 className="font-bold mb-2">{title}</h2>
31 {children}
32 </div>
33 );
34}
35
36// ── Composition ───────────────────────────────────────────────────
37export function Dashboard() {
38 return (
39 <div className="grid grid-cols-2 gap-4">
40 <Card title="RAG Pipeline">
41 <p>9 chapters covering LangChain and embeddings.</p>
42 <Button label="Read" onClick={() => console.log("navigate")} />
43 </Card>
44 <Card title="Deep Learning">
45 <p>8 chapters from perceptron to transformers.</p>
46 <Button label="Read" onClick={() => console.log("navigate")} variant="ghost" />
47 </Card>
48 </div>
49 );
50}
51
52// ── Conditional rendering ─────────────────────────────────────────
53function StatusBadge({ status }: { status: "active" | "coming" }) {
54 return (
55 <span>
56 {status === "active" ? (
57 <span className="text-green-400"> Live</span>
58 ) : (
59 <span className="text-gray-500"> Coming Soon</span>
60 )}
61 </span>
62 );
63}
64
65// ── List rendering key is required! ────────────────────────────
66function TopicList({ topics }: { topics: { id: string; label: string }[] }) {
67 return (
68 <ul>
69 {topics.map((topic) => (
70 <li key={topic.id}>{topic.label}</li> // key must be unique & stable
71 ))}
72 </ul>
73 );
74}
← PREVOverviewNEXT →2. useState & useEffect