iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Components

A React component is a function that returns JSX. Components are the units of reuse and the unit of re-render — understand them and the rest of React falls into place.

Function components + composition + keys

EXAMPLE
// 1) The simplest component
function Hello() {
    return <h1>Hello, world!</h1>;
}

// Use it like an HTML element — capital letter is REQUIRED
export default function App() {
    return <Hello />;
}

// Lowercase tags are treated as DOM elements, not components.

// 2) Props — read-only inputs
function Greeting({ name, role = 'guest' }) {
    return <p>Hi, {name} ({role})</p>;
}

<Greeting name="Mara" role="admin" />
<Greeting name="Anon" />            // role defaults to 'guest'

// 3) Children
function Card({ title, children }) {
    return (
        <section className="card">
            <h2>{title}</h2>
            <div>{children}</div>
        </section>
    );
}

<Card title="Profile">
    <p>Email: <em>mara@example.com</em></p>
    <p>Joined: <time>2024-08-01</time></p>
</Card>

// 4) Conditional rendering
function Status({ user }) {
    if (!user) return <a href="/login">Sign in</a>;
    return <span>Hi {user.name}</span>;
}

function Banner({ urgent, message }) {
    return (
        <div className={urgent ? 'banner-urgent' : 'banner'}>
            {urgent && <strong>⚠ </strong>}
            {message}
        </div>
    );
}

// 5) Lists — keys are required and must be stable
function TodoList({ todos }) {
    return (
        <ul>
            {todos.map((t) => (
                <li key={t.id} className={t.done ? 'done' : ''}>{t.text}</li>
            ))}
        </ul>
    );
}
// NEVER use array index as key for lists that reorder, filter, or insert in the middle.
// Stable IDs preserve component state across re-renders.

// 6) Composition — small components combine into big ones
function Avatar({ src, alt }) { return <img className="avatar" src={src} alt={alt} />; }
function Username({ name }) { return <span className="user">{name}</span>; }
function UserChip({ user }) {
    return (
        <div className="chip">
            <Avatar src={user.avatar} alt={user.name} />
            <Username name={user.name} />
        </div>
    );
}

// 7) State — useState
import { useState } from 'react';
function Counter() {
    const [n, setN] = useState(0);
    return (
        <button onClick={() => setN(n + 1)}>
            Clicked {n} {n === 1 ? 'time' : 'times'}
        </button>
    );
}

// Functional updater — use when next state depends on previous
<button onClick={() => setN((prev) => prev + 1)}>+1</button>

// 8) Lifting state up — siblings share via parent
function TempConverter() {
    const [c, setC] = useState(20);
    return (
        <>
            <CelsiusInput value={c} onChange={setC} />
            <FahrenheitInput value={c * 9 / 5 + 32} onChange={(f) => setC((f - 32) * 5 / 9)} />
        </>
    );
}

// 9) Memoization — only when measurably needed
import { memo, useCallback, useMemo } from 'react';

const Row = memo(function Row({ item, onSelect }) {
    return <li onClick={() => onSelect(item.id)}>{item.name}</li>;
});

function List({ items }) {
    const [selected, setSelected] = useState(null);
    const handle = useCallback((id) => setSelected(id), []);
    return items.map((i) => <Row key={i.id} item={i} onSelect={handle} />);
}

// 10) Component file conventions
//   • One main component per file, named to match the file
//   • PascalCase for components and files
//   • Co-locate small helpers; extract when shared
//   • Default export the main component; named exports for helpers

// 11) Common bugs
//   • Lowercase component name → React treats as DOM tag, fails silently
//   • Mutating props or state directly — state.x = 1 (USE setState)
//   • Using array index as key after delete/reorder → wrong state attaches
//   • Forgetting to return JSX → component renders 'undefined' (nothing)
//   • Calling hooks inside conditionals → 'Rules of Hooks' violation
//   • New object/array literal in props every render → memo doesn't help

Why it matters

Components are functions. Inputs are props, output is JSX, internal memory is state from useState — that’s the whole model. Keep components small enough that you can see the entire return at once, and trust composition to do the heavy lifting.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
function Greet({ name }) {
    return <h2>Hi, {name}</h2>;
}
function App() {
    return <Greet name="Ada" />;
}
Try it Yourself »

Discussion

Loading…