# Code Reference — React

_53 pages_

---
# React (/docs/react)



# React [#react]

Components, hooks, patterns.

Browse the sidebar for every cheat sheet in this section.

## Sections [#sections]

* [Examples](./examples)


---

# Children (/docs/react/children)



# Children [#children]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`children` is the special prop for nested content between a component’s opening and closing tags. Prefer composition with `children` over prop-drilling UI fragments.

## 🔧 Core concepts [#-core-concepts]

* **Implicit prop** — JSX between tags becomes `props.children`.
* **Any type** — string, number, element, array, `null`/`undefined`/`false` (render nothing).
* **`Children` helpers** — `Children.map`, `toArray`, `count`, `only` (use sparingly; prefer explicit arrays).
* **Slots** — multiple named slots via props (`header`, `footer`) when one `children` is not enough.

## 💡 Examples [#-examples]

```jsx
function Card({ title, children }) {
  return (
    <section className="card">
      <h2>{title}</h2>
      <div className="card-body">{children}</div>
    </section>
  );
}

<Card title="Hello">
  <p>Nested content</p>
  <button type="button">Action</button>
</Card>
```

```tsx
import { Children, type ReactNode } from "react";

type ListProps = { children: ReactNode };

function List({ children }: ListProps) {
  const items = Children.toArray(children);
  return (
    <ul>
      {items.map((child, i) => (
        <li key={i}>{child}</li>
      ))}
    </ul>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Don’t mutate `children`; treat as opaque.
* Avoid `Children.only` unless you truly require a single element.
* Keys belong on the elements you create, not on `children` itself.
* Conditional children: `\{ cond && <X /> \}` can leave `false` in the tree — usually fine, but prefer ternaries for clarity.

## 🔗 Related [#-related]

* [component.md](/docs/react/component) — function components
* [props.md](/docs/react/props) — passing data
* [jsx.md](/docs/react/jsx) — JSX nesting
* [render.md](/docs/react/render) — what gets rendered


---

# Component (/docs/react/component)



# Component [#component]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

A component is a reusable UI unit. Prefer **function components** that return JSX. Class components are legacy for new code.

## 🔧 Core concepts [#-core-concepts]

* **Function component** — `(props) => JSX`; name starts with a capital letter.
* **Pure by default** — same props → same UI; side effects go in hooks.
* **Composition** — build UIs by nesting components, not inheritance.
* **Class (legacy)** — `extends React.Component` with `render()`; use only for old codebases.

## 💡 Examples [#-examples]

```tsx
type ButtonProps = {
  label: string;
  onPress: () => void;
};

export function Button({ label, onPress }: ButtonProps) {
  return (
    <button type="button" onClick={onPress}>
      {label}
    </button>
  );
}
```

```jsx
// Legacy class form — prefer functions + hooks
import { Component } from "react";

class Counter extends Component {
  state = { n: 0 };
  render() {
    return (
      <button onClick={() => this.setState({ n: this.state.n + 1 })}>
        {this.state.n}
      </button>
    );
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Lowercase names are treated as DOM tags (`div`), not components.
* Don’t create components inside other components during render (remounts every time).
* Keep components focused; extract when JSX or logic grows.

## 🔗 Related [#-related]

* [props.md](/docs/react/props) — inputs
* [hooks.md](/docs/react/hooks) — state & effects
* [children.md](/docs/react/children) — composition
* [constructor.md](/docs/react/constructor) — class legacy


---

# Concurrent (/docs/react/concurrent)



# Concurrent [#concurrent]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Concurrent React (18+) can interrupt, prioritize, and reuse work so urgent updates (typing, clicks) stay responsive while heavier UI catches up. You opt in via APIs like `useTransition`, `useDeferredValue`, and Suspense—not by flipping a single switch beyond `createRoot`.

## 🔧 Core concepts [#-core-concepts]

* **`createRoot`** — concurrent-capable root (vs legacy `ReactDOM.render`).
* **Urgent vs transition** — input updates vs deferred UI.
* **Interruptible render** — abandoned work may restart; render must be pure.
* **Suspense** — declarative loading boundaries.
* **Streaming / RSC** — frameworks extend the model (Next.js, etc.).

## 💡 Examples [#-examples]

```tsx
import { createRoot } from "react-dom/client";
import { useState, useTransition, Suspense } from "react";

createRoot(document.getElementById("root")!).render(<App />);

function Tabs() {
  const [tab, setTab] = useState("home");
  const [isPending, startTransition] = useTransition();

  return (
    <div>
      <button
        type="button"
        onClick={() => startTransition(() => setTab("photos"))}
      >
        Photos
      </button>
      {isPending ? <span>Loading tab…</span> : null}
      <Suspense fallback={<p>Loading…</p>}>
        {tab === "photos" ? <Photos /> : <Home />}
      </Suspense>
    </div>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Side effects during render—unsafe when renders restart.
* Mutating shared objects during render.
* Assuming every setState is concurrent—only marked updates are transitions.
* Legacy mode / older roots without concurrent features.

## 🔗 Related [#-related]

* [useTransition.md](/docs/react/usetransition) — startTransition
* [useDeferredValue.md](/docs/react/usedeferredvalue) — deferred values
* [suspense.md](/docs/react/suspense) — loading UI
* [strict\_mode.md](/docs/react/strict-mode) — purity checks
* [performance.md](/docs/react/performance) — responsiveness


---

# Conditional rendering (/docs/react/conditional-rendering)



# Conditional rendering [#conditional-rendering]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Render UI selectively with JS expressions inside JSX: ternary, `&&`, early returns, or extracting components. Prefer readable conditions; avoid patterns that accidentally render `0` or `NaN`.

## 🔧 Core concepts [#-core-concepts]

* **Early return** — `if (!data) return <Loading />`.
* **Ternary** — `cond ? <A /> : <B />`.
* **`&&`** — `cond && <A />` (watch falsy numbers).
* **Switch / maps** — for multi-branch UIs.
* **Null** — `return null` renders nothing.

## 💡 Examples [#-examples]

```tsx
export function Inbox({ items, loading, error }: Props) {
  if (loading) return <p>Loading…</p>;
  if (error) return <p role="alert">{error.message}</p>;
  if (items.length === 0) return <p>No messages</p>;
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>{item.title}</li>
      ))}
    </ul>
  );
}
```

```tsx
function Badge({ count }: { count: number }) {
  // Bad: count && <span>{count}</span> renders "0"
  return count > 0 ? <span>{count}</span> : null;
}
```

```tsx
{user ? <Avatar user={user} /> : <LoginLink />}
{isAdmin && <AdminPanel />}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `count && <Badge />` when `count === 0` shows `0`.
* Nested ternaries that hurt readability—extract components.
* Hooks after conditional returns—break rules of hooks.
* Toggling with CSS-only when the subtree should unmount for state reset (or vice versa).

## 🔗 Related [#-related]

* [jsx.md](/docs/react/jsx) — expressions
* [keys\_lists.md](/docs/react/keys-lists) — empty lists
* [hooks.md](/docs/react/hooks) — hook order
* [suspense.md](/docs/react/suspense) — loading UI
* [component.md](/docs/react/component) — extract branches


---

# Constructor (/docs/react/constructor)



# Constructor [#constructor]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

In **class components**, `constructor` initializes state and binds methods. For new code, use &#x2A;*function components + `useState` / `useReducer`** instead — no constructor needed.

## 🔧 Core concepts [#-core-concepts]

* **`super(props)`** — required before using `this` in a class constructor.
* **Initial state** — `this.state = \{ ... \}` only in the constructor (or as a class field).
* **Binding** — `this.handler = this.handler.bind(this)` or class-field arrows.
* **Modern alternative** — `useState(initial)` / `useReducer` in function components.

## 💡 Examples [#-examples]

```jsx
// Legacy class constructor
import { Component } from "react";

class Form extends Component {
  constructor(props) {
    super(props);
    this.state = { value: props.initial ?? "" };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.setState({ value: e.target.value });
  }

  render() {
    return <input value={this.state.value} onChange={this.handleChange} />;
  }
}
```

```tsx
// Preferred: function + hooks
import { useState } from "react";

export function Form({ initial = "" }: { initial?: string }) {
  const [value, setValue] = useState(initial);
  return (
    <input value={value} onChange={(e) => setValue(e.target.value)} />
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Never call `setState` in the constructor; assign `this.state` directly.
* Don’t fetch data in the constructor — use `componentDidMount` (legacy) or `useEffect`.
* Copying props into state in the constructor often causes stale UI; derive or sync carefully.

## 🔗 Related [#-related]

* [component.md](/docs/react/component) — components overview
* [useState.md](/docs/react/usestate) — modern state
* [hooks.md](/docs/react/hooks) — hooks rules
* [render.md](/docs/react/render) — render lifecycle


---

# Context (/docs/react/context)



# Context [#context]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Context passes data through the tree without prop drilling. Create a context, wrap a subtree in `Provider`, consume with `useContext` or (legacy) `Context.Consumer`. Combine with custom hooks for a clean API.

## 🔧 Core concepts [#-core-concepts]

* **`createContext`** — typed default value.
* **Provider** — `value` prop is the broadcasted data.
* **Consumers** — re-render when `value` changes by `Object.is`.
* **Composition** — multiple contexts; split state vs dispatch.
* **Default** — only when no Provider ancestor exists.

## 💡 Examples [#-examples]

```tsx
import {
  createContext,
  useContext,
  useMemo,
  useState,
  type ReactNode,
} from "react";

type Auth = {
  user: { id: string; name: string } | null;
  login: (name: string) => void;
  logout: () => void;
};

const AuthContext = createContext<Auth | null>(null);

export function AuthProvider({ children }: { children: ReactNode }) {
  const [user, setUser] = useState<Auth["user"]>(null);
  const value = useMemo<Auth>(
    () => ({
      user,
      login: (name) => setUser({ id: "1", name }),
      logout: () => setUser(null),
    }),
    [user],
  );
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}

export function useAuth() {
  const ctx = useContext(AuthContext);
  if (!ctx) throw new Error("useAuth requires AuthProvider");
  return ctx;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Unstable `value` object → widespread re-renders.
* Prop drilling avoidance taken too far—pass props for local parent/child.
* Optional context without null checks.
* Putting server cache in context instead of a dedicated library when updates are frequent.

## 🔗 Related [#-related]

* [useContext.md](/docs/react/usecontext) — hook API
* [useMemo.md](/docs/react/usememo) — stable values
* [custom\_hooks.md](/docs/react/custom-hooks) — `useAuth`
* [performance.md](/docs/react/performance) — re-renders
* [children.md](/docs/react/children) — composition


---

# Custom hooks (/docs/react/custom-hooks)



# Custom hooks [#custom-hooks]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Custom hooks are functions named `useXxx` that call other hooks to reuse stateful logic (not JSX). Extract repeated effect/state patterns; keep components focused on rendering.

## 🔧 Core concepts [#-core-concepts]

* **Naming** — must start with `use` so lint rules apply.
* **Composition** — call `useState`, `useEffect`, other custom hooks.
* **Return** — values, setters, or tuples/objects—be consistent.
* **No shared state** — each call gets independent state (unless you use context/store inside).
* **Rules of Hooks** — still top-level only.

## 💡 Examples [#-examples]

```tsx
import { useCallback, useEffect, useState } from "react";

export function useToggle(initial = false) {
  const [on, setOn] = useState(initial);
  const toggle = useCallback(() => setOn((v) => !v), []);
  const setTrue = useCallback(() => setOn(true), []);
  const setFalse = useCallback(() => setOn(false), []);
  return { on, toggle, setTrue, setFalse } as const;
}
```

```tsx
export function useMediaQuery(query: string) {
  const [matches, setMatches] = useState(() =>
    typeof window !== "undefined" ? window.matchMedia(query).matches : false,
  );

  useEffect(() => {
    const mql = window.matchMedia(query);
    const onChange = () => setMatches(mql.matches);
    onChange();
    mql.addEventListener("change", onChange);
    return () => mql.removeEventListener("change", onChange);
  }, [query]);

  return matches;
}
```

```tsx
function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [error, setError] = useState<Error | null>(null);
  useEffect(() => {
    const ac = new AbortController();
    fetch(url, { signal: ac.signal })
      .then((r) => r.json())
      .then(setData)
      .catch((e) => {
        if (e.name !== "AbortError") setError(e);
      });
    return () => ac.abort();
  }, [url]);
  return { data, error };
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Returning new object literals every render without need—destructure or memoize if passed deep.
* Hiding too much: hooks that fetch + cache + toast + navigate become untestable.
* Conditional hook calls inside custom hooks.
* Forgetting cleanup (listeners, abort).

## 🔗 Related [#-related]

* [hooks.md](/docs/react/hooks) — overview
* [useEffect.md](/docs/react/useeffect) — effects
* [useContext.md](/docs/react/usecontext) — shared subscriptions
* [testing.md](/docs/react/testing) — testing hooks
* [performance.md](/docs/react/performance) — stable returns


---

# Error boundaries (/docs/react/error-boundaries)



# Error boundaries [#error-boundaries]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Error boundaries catch render/lifecycle errors in the child tree and show fallback UI instead of unmounting the whole app. They must be class components (or a library wrapper)—there is no `useErrorBoundary` built-in. They do **not** catch event handler, async, or SSR errors outside render.

## 🔧 Core concepts [#-core-concepts]

* **`getDerivedStateFromError`** — update state to show fallback.
* **`componentDidCatch`** — log to reporting service.
* **Granularity** — wrap widgets, not only the root.
* **Reset** — change `key` or provide a “try again” that clears error state.
* **vs Suspense** — Suspense = loading; boundary = failure.

## 💡 Examples [#-examples]

```tsx
import { Component, type ErrorInfo, type ReactNode } from "react";

type Props = { children: ReactNode; fallback?: ReactNode };
type State = { error: Error | null };

export class ErrorBoundary extends Component<Props, State> {
  state: State = { error: null };

  static getDerivedStateFromError(error: Error): State {
    return { error };
  }

  componentDidCatch(error: Error, info: ErrorInfo) {
    console.error("UI crash", error, info.componentStack);
  }

  render() {
    if (this.state.error) {
      return (
        this.props.fallback ?? (
          <div role="alert">
            <p>Something went wrong.</p>
            <button type="button" onClick={() => this.setState({ error: null })}>
              Try again
            </button>
          </div>
        )
      );
    }
    return this.props.children;
  }
}
```

```tsx
<ErrorBoundary>
  <Suspense fallback={<p>Loading…</p>}>
    <Profile />
  </Suspense>
</ErrorBoundary>
```

**Event handlers—catch yourself:**

```tsx
function save() {
  try {
    doSave();
  } catch (e) {
    setError(e);
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Expecting boundaries to catch `setTimeout` / `fetch` rejections automatically.
* One root boundary only—bad UX for partial failures.
* Not logging `componentDidCatch`.
* Infinite error loops if fallback throws.

## 🔗 Related [#-related]

* [suspense.md](/docs/react/suspense) — loading boundaries
* [component.md](/docs/react/component) — class vs function
* [testing.md](/docs/react/testing) — assert fallbacks
* [strict\_mode.md](/docs/react/strict-mode) — double render in dev
* [concurrent.md](/docs/react/concurrent) — render model


---

# Events (/docs/react/events)



# Events [#events]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

React uses a SyntheticEvent system: camelCase props (`onClick`, `onChange`) and functions as handlers. Behavior is consistent across browsers.

## 🔧 Core concepts [#-core-concepts]

* **Naming** — `onClick`, `onSubmit`, `onKeyDown` (not `onclick`).
* **Handler** — pass a function: `onClick=\{handleClick\}`, not `onClick=\{handleClick()\}`.
* **Event object** — `event.preventDefault()`, `event.stopPropagation()`, `event.target`.
* **Passing data** — wrap: `onClick=\{() => onSelect(id)\}` or `onClick=\{onSelect.bind(null, id)\}`.

## 💡 Examples [#-examples]

```tsx
export function SearchForm({ onSearch }: { onSearch: (q: string) => void }) {
  function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    const data = new FormData(e.currentTarget);
    onSearch(String(data.get("q") ?? ""));
  }

  return (
    <form onSubmit={handleSubmit}>
      <input name="q" type="search" />
      <button type="submit">Search</button>
    </form>
  );
}
```

```jsx
function List({ items, onSelect }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <button type="button" onClick={() => onSelect(item.id)}>
            {item.label}
          </button>
        </li>
      ))}
    </ul>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Calling the handler immediately (`onClick=\{fn()\}`) runs it during render.
* Don’t rely on the event after an `await` — React pools/reuses in older versions; read values first or use `event.persist()` only if needed on old React.
* Prefer `onChange` on inputs for controlled components, not only `onBlur`.

## 🔗 Related [#-related]

* [props.md](/docs/react/props) — callback props
* [jsx.md](/docs/react/jsx) — JSX attributes
* [useState.md](/docs/react/usestate) — controlled inputs
* [component.md](/docs/react/component) — handlers in components


---

# Examples (/docs/react/examples)



# Examples [#examples]

React notes in **Examples**.


---

# Controlled Input (/docs/react/examples/controlled-input)



# Controlled Input [#controlled-input]

*React · Example / how-to*

***

## 📋 Overview [#-overview]

Keep an input’s value in React state (controlled component) so validation and submit logic stay in sync with the UI.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                     |
| ---------------------- | ------------------------ |
| Controlled value       | `value` + `onChange`     |
| Single source of truth | State owns the string    |
| Validation             | Derive errors from state |
| Submit handler         | Read state, not DOM      |

## 💡 Examples [#-examples]

**ControlledInput.tsx:**

```tsx
import { FormEvent, useState } from "react";

export function NameForm({ onSave }: { onSave: (name: string) => void }) {
  const [name, setName] = useState("");
  const error = name.trim().length === 0 ? "Name is required" : null;

  function handleSubmit(event: FormEvent) {
    event.preventDefault();
    if (error) return;
    onSave(name.trim());
    setName("");
  }

  return (
    <form onSubmit={handleSubmit}>
      <label htmlFor="name">Name</label>
      <input
        id="name"
        value={name}
        onChange={(e) => setName(e.target.value)}
        aria-invalid={Boolean(error)}
        aria-describedby={error ? "name-error" : undefined}
      />
      {error ? (
        <p id="name-error" role="alert">
          {error}
        </p>
      ) : null}
      <button type="submit" disabled={Boolean(error)}>
        Save
      </button>
    </form>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing `defaultValue` and `value` makes the input semi-controlled — pick one.
* For checkboxes use `checked`, not `value`, as the controlled prop.
* Resetting after submit should set state to `""`, not touch the DOM.

## 🔗 Related [#-related]

* [Counter](/docs/react/examples/counter)
* [Fetch list](/docs/react/examples/fetch-list)


---

# Counter (/docs/react/examples/counter)



# Counter [#counter]

*React · Example / how-to*

***

## 📋 Overview [#-overview]

A minimal counter with `useState`: increment, decrement, and reset in a single component.

## 🔧 Core concepts [#-core-concepts]

| Piece              | Role                   |
| ------------------ | ---------------------- |
| `useState`         | Local numeric state    |
| Event handlers     | Update on click        |
| Functional updates | `setCount(c => c + 1)` |
| Derived UI         | Render current value   |

## 💡 Examples [#-examples]

**Counter.tsx:**

```tsx
import { useState } from "react";

export function Counter({ initial = 0 }: { initial?: number }) {
  const [count, setCount] = useState(initial);

  return (
    <div>
      <p aria-live="polite">Count: {count}</p>
      <button type="button" onClick={() => setCount((c) => c - 1)}>
        −
      </button>
      <button type="button" onClick={() => setCount(initial)}>
        Reset
      </button>
      <button type="button" onClick={() => setCount((c) => c + 1)}>
        +
      </button>
    </div>
  );
}
```

**Usage:**

```tsx
import { Counter } from "./Counter";

export default function App() {
  return <Counter initial={0} />;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `setCount(count + 1)` in rapid clicks can stale — prefer functional updates.
* Do not store derived values in state if they can be computed from `count`.
* Keys on lists of counters must be stable if you mount many instances.

## 🔗 Related [#-related]

* [Controlled input](/docs/react/examples/controlled-input)
* [Theme context](/docs/react/examples/theme-context)


---

# Fetch List (/docs/react/examples/fetch-list)



# Fetch List [#fetch-list]

*React · Example / how-to*

***

## 📋 Overview [#-overview]

Load a remote list in `useEffect`, track loading/error/data states, and cancel in-flight requests on unmount.

## 🔧 Core concepts [#-core-concepts]

| Piece                  | Role                   |
| ---------------------- | ---------------------- |
| `useEffect`            | Trigger fetch on mount |
| Loading / error / data | Explicit UI states     |
| `AbortController`      | Cancel on cleanup      |
| Keys                   | Stable list rendering  |

## 💡 Examples [#-examples]

**FetchList.tsx:**

```tsx
import { useEffect, useState } from "react";

type Post = { id: number; title: string };

export function FetchList() {
  const [posts, setPosts] = useState<Post[] | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const controller = new AbortController();

    async function load() {
      setLoading(true);
      setError(null);
      try {
        const res = await fetch(
          "https://jsonplaceholder.typicode.com/posts?_limit=5",
          { signal: controller.signal },
        );
        if (!res.ok) throw new Error(`HTTP ${res.status}`);
        const data = (await res.json()) as Post[];
        setPosts(data);
      } catch (err) {
        if ((err as Error).name === "AbortError") return;
        setError((err as Error).message);
      } finally {
        if (!controller.signal.aborted) setLoading(false);
      }
    }

    void load();
    return () => controller.abort();
  }, []);

  if (loading) return <p>Loading…</p>;
  if (error) return <p role="alert">Error: {error}</p>;
  if (!posts?.length) return <p>No posts</p>;

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Setting state after unmount without abort causes warnings/races.
* Empty dependency arrays only run once — add deps when the URL depends on props.
* Do not use array index as `key` if the list can reorder.

## 🔗 Related [#-related]

* [Controlled input](/docs/react/examples/controlled-input)
* [Theme context](/docs/react/examples/theme-context)


---

# Theme Context (/docs/react/examples/theme-context)



# Theme Context [#theme-context]

*React · Example / how-to*

***

## 📋 Overview [#-overview]

Share light/dark theme across the tree with `createContext`, a provider, and a small `useTheme` hook.

## 🔧 Core concepts [#-core-concepts]

| Piece        | Role                   |
| ------------ | ---------------------- |
| Context      | Avoid prop drilling    |
| Provider     | Own theme state        |
| Custom hook  | Enforce provider usage |
| `data-theme` | Drive CSS variables    |

## 💡 Examples [#-examples]

**theme\_context.tsx:**

```tsx
import {
  createContext,
  useContext,
  useEffect,
  useState,
  type ReactNode,
} from "react";

type Theme = "light" | "dark";

type ThemeContextValue = {
  theme: Theme;
  toggle: () => void;
};

const ThemeContext = createContext<ThemeContextValue | null>(null);

export function ThemeProvider({ children }: { children: ReactNode }) {
  const [theme, setTheme] = useState<Theme>("light");

  useEffect(() => {
    document.documentElement.dataset.theme = theme;
  }, [theme]);

  const value: ThemeContextValue = {
    theme,
    toggle: () => setTheme((t) => (t === "light" ? "dark" : "light")),
  };

  return (
    <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
  );
}

export function useTheme() {
  const ctx = useContext(ThemeContext);
  if (!ctx) throw new Error("useTheme must be used within ThemeProvider");
  return ctx;
}

export function ThemeToggle() {
  const { theme, toggle } = useTheme();
  return (
    <button type="button" onClick={toggle}>
      Theme: {theme}
    </button>
  );
}
```

**App wiring:**

```tsx
import { ThemeProvider, ThemeToggle } from "./theme_context";

export default function App() {
  return (
    <ThemeProvider>
      <ThemeToggle />
    </ThemeProvider>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Creating context value inline without memo can re-render broadly — fine for tiny apps; split if hot.
* Reading context outside the provider should throw a clear error.
* Persist theme separately (e.g. localStorage) if you need reload survival.

## 🔗 Related [#-related]

* [Counter](/docs/react/examples/counter)
* [Fetch list](/docs/react/examples/fetch-list)


---

# File structure (/docs/react/file-structure)



# File structure [#file-structure]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Organize by feature or route, keep components small, and colocate styles/tests. Exact layout depends on Vite, Next.js, or CRA — patterns below are common.

## 🔧 Core concepts [#-core-concepts]

* **Entry** — `main.tsx` / `index.tsx` mounts the root.
* **App shell** — `App.tsx` for providers, layout, routes.
* **Features** — `features/auth/`, `features/cart/` with local components.
* **Shared** — `components/`, `hooks/`, `lib/`, `types/`.
* **Pages/routes** — framework-specific (`pages/`, `app/`, `routes/`).

## 💡 Examples [#-examples]

```plaintext
src/
  main.tsx
  App.tsx
  components/
    Button.tsx
    Button.module.css
  features/
    todos/
      TodoList.tsx
      useTodos.ts
      api.ts
  hooks/
    useMediaQuery.ts
  lib/
    http.ts
  pages/
    HomePage.tsx
    TodoPage.tsx
```

```tsx
// main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Deep `../../../` imports — use path aliases (`@/`).
* Giant `components/` dumping ground — prefer feature folders.
* Mixing business logic into presentational files without clear boundaries.

## 🔗 Related [#-related]

* [main.md](/docs/react/main) — entry point
* [root.md](/docs/react/root) — root mount
* [pages.md](/docs/react/pages) — page components
* [import\_export.md](/docs/react/import-export) — modules


---

# Forms (/docs/react/forms)



# Forms [#forms]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

React forms are controlled (state drives inputs) or uncontrolled (refs / default values). Prefer controlled for validation and conditional UI; uncontrolled for simple or large native forms. Prevent default submit and handle async saves carefully.

## 🔧 Core concepts [#-core-concepts]

* **Controlled** — `value` + `onChange` bound to state.
* **Uncontrolled** — `defaultValue` + `ref` / `FormData`.
* **Submit** — `onSubmit` on `<form>`; `preventDefault()`.
* **Checkbox/radio** — `checked` / `selected`; groups share `name`.
* **Files** — uncontrolled `type="file"`; read via `FormData`.
* **a11y** — `label` + `useId`, error text with `aria-describedby`.

## 💡 Examples [#-examples]

**Controlled:**

```tsx
import { useState, FormEvent } from "react";

export function LoginForm({ onLogin }: { onLogin: (email: string) => void }) {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");

  function handleSubmit(e: FormEvent) {
    e.preventDefault();
    onLogin(email);
  }

  return (
    <form onSubmit={handleSubmit}>
      <label>
        Email
        <input
          type="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
          required
        />
      </label>
      <label>
        Password
        <input
          type="password"
          value={password}
          onChange={(e) => setPassword(e.target.value)}
          required
        />
      </label>
      <button type="submit">Sign in</button>
    </form>
  );
}
```

**FormData (uncontrolled):**

```tsx
function handleSubmit(e: FormEvent<HTMLFormElement>) {
  e.preventDefault();
  const data = new FormData(e.currentTarget);
  console.log(data.get("email"));
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mixing `value` without `onChange` → read-only warning.
* Using `value=\{undefined\}` then string → uncontrolled→controlled switch.
* Mutating state in place for nested form objects.
* Blocking submit button without keyboard/`Enter` considerations.

## 🔗 Related [#-related]

* [useState.md](/docs/react/usestate) — field state
* [useId.md](/docs/react/useid) — label ids
* [useRef.md](/docs/react/useref) — uncontrolled refs
* [events.md](/docs/react/events) — handlers
* [testing.md](/docs/react/testing) — user-event


---

# forwardRef (/docs/react/forwardref)



# forwardRef [#forwardref]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`forwardRef` lets a parent pass a `ref` through to a child function component (usually a DOM node or imperative handle). In React 19, `ref` can be a regular prop on function components; `forwardRef` remains common in existing code and libraries.

## 🔧 Core concepts [#-core-concepts]

* **Classic** — `forwardRef((props, ref) => ...)`.
* **React 19** — `function Input(\{ ref, ...props \})` may work without forwardRef.
* **`useImperativeHandle`** — expose a custom instance API instead of the raw DOM node.
* **Typing** — `forwardRef<HTMLInputElement, Props>(...)`.

## 💡 Examples [#-examples]

```tsx
import { forwardRef, useImperativeHandle, useRef } from "react";

type Props = { label: string };

export const TextField = forwardRef<HTMLInputElement, Props>(function TextField(
  { label },
  ref,
) {
  return (
    <label>
      {label}
      <input ref={ref} />
    </label>
  );
});
```

**Imperative handle:**

```tsx
type Handle = { focus: () => void; clear: () => void };

export const FancyInput = forwardRef<Handle, object>(function FancyInput(_, ref) {
  const inputRef = useRef<HTMLInputElement>(null);
  useImperativeHandle(ref, () => ({
    focus: () => inputRef.current?.focus(),
    clear: () => {
      if (inputRef.current) inputRef.current.value = "";
    },
  }));
  return <input ref={inputRef} />;
});
```

**Usage:**

```tsx
const ref = useRef<HTMLInputElement>(null);
<TextField ref={ref} label="Email" />;
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting to attach `ref` to a real host component.
* Exposing entire component internals via imperative handles—prefer props.
* Breaking memoization by wrapping inconsistently.
* Type mismatches between `ref` and DOM element.

## 🔗 Related [#-related]

* [useRef.md](/docs/react/useref) — refs
* [forms.md](/docs/react/forms) — focus management
* [component.md](/docs/react/component) — components
* [hooks.md](/docs/react/hooks) — useImperativeHandle
* [memo.md](/docs/react/memo) — composed components


---

# Fragments (/docs/react/fragments)



# Fragments [#fragments]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Fragments group children without adding an extra DOM node. Use `&lt;>...&lt;/>` or `<Fragment>` when a component must return multiple siblings. Keyed fragments need the long form.

## 🔧 Core concepts [#-core-concepts]

* **Short syntax** — `&lt;>...&lt;/>` (no props, no key).
* **Long form** — `<Fragment key=\{...\}>`.
* **No DOM** — doesn’t affect layout/CSS selectors as a wrapper.
* **Return** — components return one parent; fragment counts as one.

## 💡 Examples [#-examples]

```tsx
import { Fragment } from "react";

export function DefinitionList({
  items,
}: {
  items: { id: string; term: string; description: string }[];
}) {
  return (
    <dl>
      {items.map((item) => (
        <Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </Fragment>
      ))}
    </dl>
  );
}
```

```tsx
function Columns() {
  return (
    <>
      <td>A</td>
      <td>B</td>
    </>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Trying to pass `key` to `&lt;>...&lt;/>`—use `Fragment`.
* Wrapping with `<div>` unnecessarily and breaking tables/flex.
* Assuming fragments create a styling target—they don’t.
* Returning arrays without keys when mapping.

## 🔗 Related [#-related]

* [keys\_lists.md](/docs/react/keys-lists) — keyed lists
* [jsx.md](/docs/react/jsx) — JSX shape
* [children.md](/docs/react/children) — child composition
* [component.md](/docs/react/component) — return types
* [conditional\_rendering.md](/docs/react/conditional-rendering) — multiple branches


---

# Getting Started with React (/docs/react/getting-started)



# Getting Started with React [#getting-started-with-react]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

React is a JavaScript library for building user interfaces from **components** — reusable pieces of UI that describe what should appear for a given state. You write components with JSX (HTML-like syntax in JS) and React updates the DOM efficiently.

## 🔧 Core concepts [#-core-concepts]

| Idea      | Meaning                                      |
| --------- | -------------------------------------------- |
| Component | Function that returns UI                     |
| JSX       | Syntax extension: `<Button />` in JS         |
| Props     | Inputs passed into a component               |
| State     | Data that can change over time               |
| Render    | Computing UI from props + state              |
| Hook      | `useState`, `useEffect`, … for state/effects |

Beginners usually start with **Vite + React** or Next.js, not CDN scripts alone.

## 💡 Examples [#-examples]

**Create a Vite React app:**

```shellscript
npm create vite@latest my-app -- --template react
cd my-app
npm install
npm run dev
```

**A tiny component:**

```jsx
function Hello() {
  return <h1>Hello, React</h1>;
}

export default function App() {
  return (
    <main>
      <Hello />
    </main>
  );
}
```

**Props:**

```jsx
function Greeting({ name }) {
  return <p>Hello, {name}!</p>;
}

// <Greeting name="Ada" />
```

**State with useState:**

```jsx
import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button type="button" onClick={() => setCount(count + 1)}>
      Clicked {count}
    </button>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* JSX requires a build step (or a modern toolchain) — browsers don’t run raw JSX.
* Mutating state in place won’t re-render — use the setter (`setCount`).
* Component names must start with a **Capital** letter.
* Don’t forget to import React hooks from `"react"`.

## 🔗 Related [#-related]

* [hello\_world.md](/docs/react/hello-world)
* [thinking\_in\_react.md](/docs/react/thinking-in-react)
* [conditional\_rendering.md](/docs/react/conditional-rendering)
* [keys\_lists.md](/docs/react/keys-lists)


---

# Glossary (/docs/react/glossary)



# Glossary [#glossary]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Alphabetical glossary of core React terms for components, hooks, rendering, and common UI patterns.

## 🔧 Core concepts [#-core-concepts]

| Term               | Definition                                                                            |
| ------------------ | ------------------------------------------------------------------------------------- |
| Children           | Nested content passed between a component’s opening and closing tags.                 |
| Component          | A function or class that returns UI described with JSX/elements.                      |
| Concurrent         | React’s ability to interrupt, prioritize, and resume rendering work.                  |
| Context            | A way to pass data through the tree without prop drilling.                            |
| Controlled input   | A form element whose value is driven by React state.                                  |
| Custom hook        | A function named `use*` that reuses stateful logic across components.                 |
| Effect             | Side-work scheduled with `useEffect` after paint (or layout effects).                 |
| Element            | A plain object describing what to render, usually created via JSX.                    |
| Error boundary     | A class component that catches render errors in its subtree.                          |
| Fiber              | React’s internal unit of work representing a component instance.                      |
| Fragment           | A wrapper (`&lt;>...&lt;/>` or `<Fragment>`) that groups children without a DOM node. |
| Hook               | A special function that lets function components use state and React features.        |
| Hydration          | Attaching event handlers to server-rendered HTML on the client.                       |
| JSX                | Syntax extension that looks like HTML and compiles to `React.createElement` calls.    |
| Key                | A stable identity string helping React match list items across updates.               |
| Memo               | `React.memo` or `useMemo` techniques that skip redundant work.                        |
| Portal             | Rendering children into a DOM node outside the parent hierarchy.                      |
| Props              | Inputs passed from parent to child; treated as read-only by the child.                |
| Reconciliation     | Diffing previous and next trees to decide minimal DOM updates.                        |
| Ref                | A mutable container (`useRef`/`createRef`) that persists across renders.              |
| Render             | Calling a component to produce elements for a given props/state.                      |
| State              | Data owned by a component that triggers re-render when updated.                       |
| Strict Mode        | A development wrapper that highlights unsafe patterns and double-invokes some APIs.   |
| Suspense           | A boundary that shows fallback UI while lazy or async children load.                  |
| Transition         | A lower-priority state update marked with `startTransition`/`useTransition`.          |
| Uncontrolled input | A form element that keeps its value in the DOM, often read via a ref.                 |
| Virtual DOM        | The in-memory element tree React diffs before touching the real DOM.                  |

## 💡 Examples [#-examples]

**State and effect:**

```tsx
function Counter() {
  const [n, setN] = useState(0);
  useEffect(() => {
    document.title = `Count ${n}`;
  }, [n]);
  return <button onClick={() => setN((x) => x + 1)}>{n}</button>;
}
```

**Context and children:**

```tsx
const Theme = createContext("light");
function App({ children }: { children: React.ReactNode }) {
  return <Theme.Provider value="dark">{children}</Theme.Provider>;
}
```

**Keys in lists:**

```tsx
{items.map((item) => (
  <li key={item.id}>{item.label}</li>
))}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Confusing **props** (from parent) with **state** (owned locally).
* Mixing **controlled** and **uncontrolled** inputs on the same field.
* Using array **index** as **key** when list order or identity can change.
* Treating **memo** as free performance — it only helps when props are stable.
* Equating **useEffect** with “run on mount only” — dependency arrays control that.

## 🔗 Related [#-related]

* [hooks](/docs/react/hooks)
* [useState](/docs/react/usestate)
* [useEffect](/docs/react/useeffect)
* [props](/docs/react/props)
* [context](/docs/react/context)
* [jsx](/docs/react/jsx)


---

# Hello World (/docs/react/hello-world)



# Hello World [#hello-world]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

React Hello World is a component that returns a simple element (often an `<h1>`). Once it appears in the browser via your app’s root render, your toolchain is working.

## 🔧 Core concepts [#-core-concepts]

| Piece          | Role                                           |
| -------------- | ---------------------------------------------- |
| Root           | `createRoot(...).render(<App />)` mounts React |
| `App`          | Top-level component                            |
| `return (...)` | JSX describing UI                              |
| Export         | Makes the component importable                 |

In Vite, `main.jsx` mounts `<App />` into `#root`.

## 💡 Examples [#-examples]

**Minimal App:**

```jsx
export default function App() {
  return <h1>Hello, World!</h1>;
}
```

**With a child component:**

```jsx
function Hello() {
  return <h1>Hello, World!</h1>;
}

export default function App() {
  return (
    <div>
      <Hello />
      <p>Welcome to React.</p>
    </div>
  );
}
```

**Mount (Vite-style `main.jsx`):**

```jsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App.jsx";

createRoot(document.getElementById("root")).render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

**Expression in JSX:**

```jsx
const name = "Ada";
export default function App() {
  return <h1>Hello, {name}!</h1>;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `getElementById("root")` must match an element in `index.html`.
* Returning two sibling elements needs a wrapper or fragment (`&lt;>...&lt;/>`).
* `class` in JSX is written `className`.
* Browser console errors are your friend — read the first red message carefully.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/react/getting-started)
* [thinking\_in\_react.md](/docs/react/thinking-in-react)
* [fragments.md](/docs/react/fragments)
* [strict\_mode.md](/docs/react/strict-mode)


---

# Hooks (/docs/react/hooks)



# Hooks [#hooks]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Hooks let function components use state, lifecycle, and shared logic. Call them only at the top level of React functions (components or custom hooks).

## 🔧 Core concepts [#-core-concepts]

* **Built-ins** — `useState`, `useEffect`, `useContext`, `useRef`, `useMemo`, `useCallback`, `useReducer`, `useId`, …
* **Rules** — top level only; only in React functions; same order every render.
* **Custom hooks** — `useXxx` functions that call other hooks; share stateful logic.
* **Classes** — no hooks; use lifecycle methods (legacy).

## 💡 Examples [#-examples]

```tsx
import { useState, useEffect } from "react";

export function useDocumentTitle(title: string) {
  useEffect(() => {
    document.title = title;
  }, [title]);
}

export function Counter() {
  const [count, setCount] = useState(0);
  useDocumentTitle(`Count: ${count}`);
  return (
    <button type="button" onClick={() => setCount((c) => c + 1)}>
      {count}
    </button>
  );
}
```

```jsx
function useToggle(initial = false) {
  const [on, setOn] = useState(initial);
  const toggle = () => setOn((v) => !v);
  return [on, toggle];
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Conditional / looped hook calls break React’s hook order.
* Missing dependency arrays cause stale closures or infinite loops.
* `useMemo` / `useCallback` are not free — use when measured or required for referential equality.

## 🔗 Related [#-related]

* [useState.md](/docs/react/usestate) — state
* [useEffect.md](/docs/react/useeffect) — effects
* [component.md](/docs/react/component) — function components
* [constructor.md](/docs/react/constructor) — class alternative (legacy)


---

# Import / Export (/docs/react/import-export)



# Import / Export [#import--export]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

React apps use ES modules: `import` / `export`. Prefer **named exports** for components and utilities; default exports are fine for route-level pages when the framework expects them.

## 🔧 Core concepts [#-core-concepts]

* **Named** — `export function Button` → `import \{ Button \} from "./Button"`.
* **Default** — `export default App` → `import App from "./App"`.
* **Re-export** — `export \{ Button \} from "./Button"` for barrel files.
* **Type-only** — `import type \{ Props \} from "./types"` (TypeScript).
* **CSS / assets** — `import "./styles.css"`, `import logo from "./logo.svg"`.

## 💡 Examples [#-examples]

```tsx
// Button.tsx
export type ButtonProps = { label: string };

export function Button({ label }: ButtonProps) {
  return <button type="button">{label}</button>;
}
```

```tsx
// App.tsx
import { Button } from "./components/Button";
import type { ButtonProps } from "./components/Button";
import "./App.css";

export function App() {
  const props: ButtonProps = { label: "Save" };
  return <Button {...props} />;
}
```

```js
// barrel: components/index.ts
export { Button } from "./Button";
export { Input } from "./Input";
```

## ⚠️ Pitfalls [#️-pitfalls]

* Circular imports between components — extract shared modules.
* Mixing default and named for the same symbol confuses refactors.
* Side-effect imports order can matter for CSS cascade.

## 🔗 Related [#-related]

* [file\_structure.md](/docs/react/file-structure) — where modules live
* [component.md](/docs/react/component) — exporting components
* [tsx.md](/docs/react/tsx) — TypeScript modules
* [main.md](/docs/react/main) — entry imports


---

# JSX (/docs/react/jsx)



# JSX [#jsx]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

JSX is syntax sugar for `React.createElement` / the JSX transform. It looks like HTML in JavaScript but follows JavaScript rules for expressions and attributes.

## 🔧 Core concepts [#-core-concepts]

* **Expressions** — `\{value\}` inside tags; any JS expression is allowed.
* **Attributes** — camelCase (`className`, `htmlFor`, `onClick`); strings in quotes or `\{expr\}`.
* **One parent** — return a single root, fragment `&lt;>...&lt;/>`, or array.
* **Self-closing** — `<img />`, `<Component />` when no children.
* **Booleans** — `disabled=\{isOff\}`; omit or pass `true` for presence flags.

## 💡 Examples [#-examples]

```jsx
const name = "Ada";
const el = (
  <>
    <h1 className="title">Hello, {name}</h1>
    <img src="/avatar.png" alt="" />
    {items.length > 0 ? (
      <ul>
        {items.map((item) => (
          <li key={item.id}>{item.label}</li>
        ))}
      </ul>
    ) : (
      <p>Empty</p>
    )}
  </>
);
```

```tsx
type IconProps = { size?: number };

function Icon({ size = 16 }: IconProps) {
  return <svg width={size} height={size} aria-hidden />;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `class` → `className`; `for` → `htmlFor`.
* `style` takes an object: `style=\{\{ marginTop: 8 \}\}`, not a CSS string (unless using libraries).
* Comments: `\{/* comment */\}`, not `&lt;!-- -->`.
* `if` statements aren’t expressions — use ternaries or extract variables.

## 🔗 Related [#-related]

* [tsx.md](/docs/react/tsx) — typed JSX
* [tag.md](/docs/react/tag) — elements & tags
* [children.md](/docs/react/children) — nested content
* [component.md](/docs/react/component) — custom tags


---

# Keys & lists (/docs/react/keys-lists)



# Keys & lists [#keys--lists]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

When rendering lists, each sibling needs a stable `key` so React can match items across updates. Keys should identify the item (id), not its position. Correct keys preserve state and avoid buggy remounts.

## 🔧 Core concepts [#-core-concepts]

* **Purpose** — identity for reconciliation, not display.
* **Stable** — same item → same key across renders.
* **Unique among siblings** — not globally unique required.
* **Avoid index** — unless the list is static and never reorders.
* **Reset state** — changing `key` on a component remounts it.

## 💡 Examples [#-examples]

```tsx
type Todo = { id: string; text: string; done: boolean };

export function TodoList({ todos }: { todos: Todo[] }) {
  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>
          <TodoRow todo={todo} />
        </li>
      ))}
    </ul>
  );
}
```

**Remount to reset form:**

```tsx
<Editor key={selectedId} documentId={selectedId} />
```

**Fragments with keys:**

```tsx
{items.map((item) => (
  <Fragment key={item.id}>
    <dt>{item.term}</dt>
    <dd>{item.description}</dd>
  </Fragment>
))}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `key=\{index\}` with insert/reorder/delete → wrong state on inputs.
* Random keys (`Math.random()`) every render → remount thrash.
* Using array index after sorting/filtering.
* Putting key on the wrong element (must be on the outermost mapped element).

## 🔗 Related [#-related]

* [fragments.md](/docs/react/fragments) — keyed fragments
* [conditional\_rendering.md](/docs/react/conditional-rendering) — list empty states
* [jsx.md](/docs/react/jsx) — expressions
* [performance.md](/docs/react/performance) — list virtualization
* [memo.md](/docs/react/memo) — row memoization


---

# Layout (/docs/react/layout)



# Layout [#layout]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Layout in React is ordinary DOM + CSS (Flexbox, Grid, modules, Tailwind). Components compose shells: header, sidebar, main, footer — often via nested routes or layout wrappers.

## 🔧 Core concepts [#-core-concepts]

* **Shell components** — `AppLayout`, `AuthLayout` wrap page content with `children`.
* **CSS approach** — CSS Modules, Tailwind, styled-components, plain CSS — pick one stack.
* **Responsive** — media queries or container queries; avoid hard-coded pixel-only UIs.
* **Portals** — modals/tooltips via `createPortal` to escape overflow/stacking contexts.

## 💡 Examples [#-examples]

```tsx
import type { ReactNode } from "react";

export function AppLayout({ children }: { children: ReactNode }) {
  return (
    <div className="app">
      <header className="app-header">Brand</header>
      <div className="app-body">
        <aside className="app-nav">Nav</aside>
        <main className="app-main">{children}</main>
      </div>
    </div>
  );
}
```

```css
.app {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
.app-body {
  flex: 1;
  display: grid;
  grid-template-columns: 240px 1fr;
}
.app-main {
  padding: 1.5rem;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Nesting too many layout wrappers without clear ownership.
* Fixed heights that break on mobile keyboards / dynamic viewport.
* Forgetting `min-width: 0` on flex/grid children that overflow.

## 🔗 Related [#-related]

* [pages.md](/docs/react/pages) — page content inside layouts
* [children.md](/docs/react/children) — layout slots
* [root.md](/docs/react/root) — app root
* [file\_structure.md](/docs/react/file-structure) — where layouts live


---

# Main (/docs/react/main)



# Main [#main]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`main.tsx` / `main.jsx` (or `index.tsx`) is the **entry module**: it finds the DOM node and mounts the React tree with `createRoot`.

## 🔧 Core concepts [#-core-concepts]

* **`createRoot`** — React 18+ API from `react-dom/client`.
* **`StrictMode`** — double-invokes effects in dev to surface unsafe patterns.
* **Providers** — wrap `App` with router, query client, theme, auth.
* **Legacy** — `ReactDOM.render` is removed in React 19; migrate to `createRoot`.

## 💡 Examples [#-examples]

```tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { App } from "./App";
import "./index.css";

const el = document.getElementById("root");
if (!el) throw new Error("Root element #root not found");

createRoot(el).render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>,
);
```

```html
<!-- index.html -->
<body>
  <div id="root"></div>
  <script type="module" src="/src/main.tsx"></script>
</body>
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mounting twice on the same node without `root.unmount()`.
* Missing `#root` in HTML → silent or thrown failure.
* Putting heavy logic in `main` instead of `App` / feature modules.

## 🔗 Related [#-related]

* [root.md](/docs/react/root) — root API details
* [file\_structure.md](/docs/react/file-structure) — project layout
* [pages.md](/docs/react/pages) — routed pages
* [import\_export.md](/docs/react/import-export) — entry imports


---

# memo (/docs/react/memo)



# memo [#memo]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`memo(Component)` wraps a function component so React skips re-rendering when props are shallowly equal (`Object.is` per prop). Use after measuring; unstable callback/object props defeat it unless memoized.

## 🔧 Core concepts [#-core-concepts]

* **Shallow compare** — default prop equality.
* **Custom compare** — `memo(Comp, (prev, next) => boolean)` (return true to skip).
* **Children** — `children` prop changes often; be careful.
* **Compiler** — React Compiler may auto-memoize; manual `memo` still fine.
* **Pair with** — `useCallback` / `useMemo` for stable props.

## 💡 Examples [#-examples]

```tsx
import { memo } from "react";

type Props = { name: string; active: boolean; onSelect: () => void };

export const UserRow = memo(function UserRow({ name, active, onSelect }: Props) {
  return (
    <button type="button" aria-pressed={active} onClick={onSelect}>
      {name}
    </button>
  );
});
```

**Custom equality:**

```tsx
const Chart = memo(
  function Chart({ data }: { data: number[] }) {
    return <canvas />;
  },
  (prev, next) =>
    prev.data.length === next.data.length &&
    prev.data.every((v, i) => v === next.data[i]),
);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Memoizing everything—noise and complexity.
* Passing inline `onClick=\{() => ...\}` or `style=\{\{\}\}` → always re-render.
* Expecting `memo` to deep-compare objects.
* Skipping renders that must update from context—context still forces update when consumed.

## 🔗 Related [#-related]

* [useCallback.md](/docs/react/usecallback) — stable handlers
* [useMemo.md](/docs/react/usememo) — stable values
* [performance.md](/docs/react/performance) — profiling
* [component.md](/docs/react/component) — function components
* [keys\_lists.md](/docs/react/keys-lists) — list rows


---

# Pages (/docs/react/pages)



# Pages [#pages]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Pages are route-level screens: they compose features, fetch data, and sit inside layouts. In SPAs they map to router routes; in Next.js / Remix they are file-based routes.

## 🔧 Core concepts [#-core-concepts]

* **Thin pages** — orchestrate; push UI into feature components.
* **Data** — loaders, React Query, or `useEffect` + fetch (prefer dedicated data libs).
* **Params** — `useParams`, `useSearchParams` from the router.
* **Code splitting** — `lazy(() => import("./Page"))` + `Suspense`.

## 💡 Examples [#-examples]

```tsx
import { useParams } from "react-router-dom";
import { TodoList } from "../features/todos/TodoList";

export function TodoPage() {
  const { listId } = useParams<{ listId: string }>();
  if (!listId) return <p>Missing list</p>;
  return (
    <section>
      <h1>List {listId}</h1>
      <TodoList listId={listId} />
    </section>
  );
}
```

```tsx
import { lazy, Suspense } from "react";
import { Route, Routes } from "react-router-dom";

const TodoPage = lazy(() =>
  import("./pages/TodoPage").then((m) => ({ default: m.TodoPage })),
);

export function AppRoutes() {
  return (
    <Suspense fallback={<p>Loading…</p>}>
      <Routes>
        <Route path="/lists/:listId" element={<TodoPage />} />
      </Routes>
    </Suspense>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Fat pages with all business logic — hard to test and reuse.
* Fetching the same data in every page without a cache layer.
* Forgetting loading and error UI for async pages.

## 🔗 Related [#-related]

* [layout.md](/docs/react/layout) — page shells
* [file\_structure.md](/docs/react/file-structure) — where pages live
* [hooks.md](/docs/react/hooks) — data hooks
* [main.md](/docs/react/main) — app entry


---

# Performance (/docs/react/performance)



# Performance [#performance]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Optimize after measuring (React DevTools Profiler, browser performance). Biggest wins: fewer unnecessary re-renders, smaller JS bundles, virtualized long lists, and concurrent features for responsiveness. Avoid premature `memo` everywhere.

## 🔧 Core concepts [#-core-concepts]

| Lever      | Technique                                    |
| ---------- | -------------------------------------------- |
| Re-renders | `memo`, stable props, split context          |
| Bundles    | `lazy` + `Suspense`, route splitting         |
| Lists      | windowing (`react-window` / FlashList on RN) |
| Urgency    | `useTransition` / `useDeferredValue`         |
| Images     | correct size, lazy load, modern formats      |
| State      | lift only as high as needed; colocate        |

Profile → find slow commits → fix the cause.

## 💡 Examples [#-examples]

```tsx
import { lazy, Suspense, memo, useCallback, useState } from "react";

const HeavyChart = lazy(() => import("./HeavyChart"));

const Row = memo(function Row({
  id,
  onSelect,
}: {
  id: string;
  onSelect: (id: string) => void;
}) {
  return (
    <button type="button" onClick={() => onSelect(id)}>
      {id}
    </button>
  );
});

export function Dashboard({ ids }: { ids: string[] }) {
  const [selected, setSelected] = useState<string | null>(null);
  const onSelect = useCallback((id: string) => setSelected(id), []);

  return (
    <>
      {ids.map((id) => (
        <Row key={id} id={id} onSelect={onSelect} />
      ))}
      <Suspense fallback={<p>Loading chart…</p>}>
        {selected ? <HeavyChart id={selected} /> : null}
      </Suspense>
    </>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Optimizing without a profile.
* Giant context values updating every keystroke.
* Anonymous components defined inside parents (`function Row` inside render).
* Derived state duplicated instead of computing during render.
* Huge lists without virtualization.

## 🔗 Related [#-related]

* [memo.md](/docs/react/memo) — skip renders
* [useMemo.md](/docs/react/usememo) / [useCallback.md](/docs/react/usecallback)
* [useTransition.md](/docs/react/usetransition) — responsiveness
* [suspense.md](/docs/react/suspense) — code split
* [keys\_lists.md](/docs/react/keys-lists) — list identity


---

# Portals (/docs/react/portals)



# Portals [#portals]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`createPortal(child, domNode)` renders children into a DOM node outside the parent hierarchy while preserving React context and event bubbling in the React tree. Use for modals, tooltips, and toasts that must escape `overflow: hidden` or stacking contexts.

## 🔧 Core concepts [#-core-concepts]

* **API** — `createPortal(reactNode, container, key?)`.
* **Events** — bubble through React parents, not necessarily DOM parents.
* **Context** — still sees the React tree Providers.
* **SSR** — ensure the target node exists or gate on client.
* **Cleanup** — unmount removes portal children; manage container lifetime.

## 💡 Examples [#-examples]

```tsx
import { useEffect, useState } from "react";
import { createPortal } from "react-dom";

export function Modal({
  open,
  onClose,
  children,
}: {
  open: boolean;
  onClose: () => void;
  children: React.ReactNode;
}) {
  if (!open) return null;
  return createPortal(
    <div
      role="dialog"
      aria-modal="true"
      style={{
        position: "fixed",
        inset: 0,
        background: "rgba(0,0,0,0.4)",
        display: "grid",
        placeItems: "center",
      }}
      onClick={onClose}
    >
      <div onClick={(e) => e.stopPropagation()}>{children}</div>
    </div>,
    document.body,
  );
}
```

**Dedicated mount node:**

```tsx
const el = document.getElementById("modal-root");
return el ? createPortal(content, el) : null;
```

## ⚠️ Pitfalls [#️-pitfalls]

* Forgetting focus trap / `Escape` / `aria-modal` for dialogs.
* Portal target missing during SSR/hydration.
* Relying on DOM parent CSS (inheritance) that no longer applies.
* Stopping propagation incorrectly so overlay clicks don’t close.

## 🔗 Related [#-related]

* [jsx.md](/docs/react/jsx) — rendering
* [events.md](/docs/react/events) — bubbling
* [context.md](/docs/react/context) — context still works
* [useEffect.md](/docs/react/useeffect) — lock body scroll
* [fragments.md](/docs/react/fragments) — grouping without nodes


---

# Props (/docs/react/props)



# Props [#props]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Props are the inputs to a component — read-only data and callbacks from the parent. Type them with TypeScript; validate shapes at boundaries when needed.

## 🔧 Core concepts [#-core-concepts]

* **Immutable** — never mutate `props`; lift state or use local state instead.
* **Destructuring** — `function Button(\{ label, onClick \})`.
* **Defaults** — default parameters or `defaultProps` (prefer parameters).
* **Spread** — `<Button \{...rest\} />` for passthrough DOM props.
* **Children** — special prop for nested content (see children.md).

## 💡 Examples [#-examples]

```tsx
type AvatarProps = {
  name: string;
  size?: number;
  onClick?: () => void;
};

export function Avatar({ name, size = 40, onClick }: AvatarProps) {
  return (
    <button type="button" onClick={onClick} style={{ width: size, height: size }}>
      {name.slice(0, 1)}
    </button>
  );
}
```

```jsx
function UserCard({ user, ...rest }) {
  return (
    <article {...rest}>
      <Avatar name={user.name} />
      <p>{user.email}</p>
    </article>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Mutating props or nested objects from props.
* Passing new inline objects/functions when child memoization depends on referential equality — measure before optimizing.
* Prop drilling deep trees — use composition or context.

## 🔗 Related [#-related]

* [component.md](/docs/react/component) — receiving props
* [children.md](/docs/react/children) — children prop
* [events.md](/docs/react/events) — callback props
* [tsx.md](/docs/react/tsx) — typing props


---

# Render (/docs/react/render)



# Render [#render]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Rendering is React turning component output into the UI. Function components **return** JSX; React reconciles changes and updates the DOM. Class components use a `render()` method (legacy).

## 🔧 Core concepts [#-core-concepts]

* **Return value** — element, fragment, string/number, `null`/`false`/`undefined` (nothing).
* **Re-render** — state/props/context change schedules an update.
* **Reconciliation** — keys help match list items across updates.
* **Class `render()`** — pure method; no side effects (legacy).

## 💡 Examples [#-examples]

```tsx
export function Status({ ok }: { ok: boolean }) {
  if (!ok) return null;
  return <span className="ok">Ready</span>;
}
```

```jsx
function List({ items }) {
  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>{item.label}</li>
      ))}
    </ul>
  );
}
```

```jsx
// Legacy class
class Badge extends React.Component {
  render() {
    return <span>{this.props.label}</span>;
  }
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Side effects during render (subscriptions, fetches) — use `useEffect`.
* Unstable list keys (`index` when order changes) cause wrong state reuse.
* Returning `undefined` accidentally (missing `return`) shows nothing / warnings.

## 🔗 Related [#-related]

* [component.md](/docs/react/component) — what returns JSX
* [root.md](/docs/react/root) — initial mount
* [jsx.md](/docs/react/jsx) — JSX output
* [useState.md](/docs/react/usestate) — triggers re-render


---

# Root (/docs/react/root)



# Root [#root]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

The **root** is the React 18+ mount point created with `createRoot(domNode)`. It owns the tree: `render`, `unmount`, and concurrent features.

## 🔧 Core concepts [#-core-concepts]

* **`createRoot(container)`** — returns a root object.
* **`root.render(<App />)`** — mount or update the tree.
* **`root.unmount()`** — tear down listeners and DOM React owns.
* **Hydration** — `hydrateRoot` for SSR; match server HTML.

## 💡 Examples [#-examples]

```tsx
import { createRoot } from "react-dom/client";
import { App } from "./App";

const container = document.getElementById("root")!;
const root = createRoot(container);
root.render(<App />);

// Later (e.g. microfrontend teardown):
// root.unmount();
```

```tsx
import { hydrateRoot } from "react-dom/client";
import { App } from "./App";

hydrateRoot(document.getElementById("root")!, <App />);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Calling `createRoot` twice on the same node without unmounting.
* Using deprecated `ReactDOM.render` on React 18+.
* Hydration mismatches (different server vs client markup) cause warnings and remounts.

## 🔗 Related [#-related]

* [main.md](/docs/react/main) — typical entry usage
* [render.md](/docs/react/render) — what gets rendered
* [file\_structure.md](/docs/react/file-structure) — project entry
* [layout.md](/docs/react/layout) — top-level UI


---

# Router (/docs/react/router)



# Router [#router]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Client-side routing maps URLs to components. In React apps, **React Router** (v6/v7) is the common SPA choice; Next.js / Remix use file-based routers. Core ideas: route config, nested layouts, loaders/actions (data routers), and links that don’t full-reload.

## 🔧 Core concepts [#-core-concepts]

| Concept                            | Role                           |
| ---------------------------------- | ------------------------------ |
| `BrowserRouter` / `RouterProvider` | History + route tree           |
| `Routes` / `Route`                 | Match path → element           |
| `Link` / `NavLink`                 | Declarative navigation         |
| `useNavigate` / `useParams`        | Imperative / params            |
| Nested routes                      | Layout + `<Outlet />`          |
| Loaders                            | Data before render (data APIs) |

Prefer path params and search params over ad-hoc global state for shareable URLs.

## 💡 Examples [#-examples]

```tsx
import {
  createBrowserRouter,
  RouterProvider,
  Link,
  Outlet,
  useParams,
} from "react-router-dom";

function RootLayout() {
  return (
    <div>
      <nav>
        <Link to="/">Home</Link>
        <Link to="/posts/1">Post</Link>
      </nav>
      <Outlet />
    </div>
  );
}

function Post() {
  const { id } = useParams();
  return <h1>Post {id}</h1>;
}

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      { index: true, element: <p>Home</p> },
      { path: "posts/:id", element: <Post /> },
    ],
  },
]);

export function App() {
  return <RouterProvider router={router} />;
}
```

**Navigate:**

```tsx
const navigate = useNavigate();
navigate("/login", { replace: true });
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using `<a href>` for in-app routes → full reload.
* Forgetting nested `<Outlet />`.
* Matching order / missing splat routes for 404.
* Putting auth redirects only in UI without loader/guard protection.

## 🔗 Related [#-related]

* [suspense.md](/docs/react/suspense) — lazy routes
* [layout.md](/docs/react/layout) — nested layouts
* [pages.md](/docs/react/pages) — page components
* [error\_boundaries.md](/docs/react/error-boundaries) — route errors
* [performance.md](/docs/react/performance) — code splitting


---

# Strict Mode (/docs/react/strict-mode)



# Strict Mode [#strict-mode]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<StrictMode>` enables extra development checks: double-invoking render/effects (React 18+), warning on deprecated APIs, and detecting unsafe lifecycles. It does not affect production builds. Prefer wrapping the app root during development.

## 🔧 Core concepts [#-core-concepts]

* **Dev-only** — no production behavior change.
* **Double effects** — mount → unmount → remount to surface missing cleanups.
* **Double render** — helps find impure renders.
* **Nested** — can wrap subsections.
* **Not a performance tool** — diagnostics only.

## 💡 Examples [#-examples]

```tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);
```

**Effect that survives Strict Mode:**

```tsx
useEffect(() => {
  const ac = new AbortController();
  fetch("/api", { signal: ac.signal }).then(/* ... */);
  return () => ac.abort(); // required — runs on simulated remount
}, []);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Thinking double-fetch in dev is a production bug—check cleanup first.
* Impure renders (Math.random in render, mutating props)—Strict Mode exposes them.
* Removing Strict Mode to “fix” bugs instead of fixing cleanups.
* Expecting warnings for all async race conditions—it won’t catch everything.

## 🔗 Related [#-related]

* [useEffect.md](/docs/react/useeffect) — cleanup
* [root.md](/docs/react/root) — createRoot
* [concurrent.md](/docs/react/concurrent) — concurrent features
* [testing.md](/docs/react/testing) — act / cleanup
* [hooks.md](/docs/react/hooks) — purity


---

# Suspense (/docs/react/suspense)



# Suspense [#suspense]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`<Suspense fallback=\{...\}>` shows fallback UI while children are loading (lazy components, React 19 resource reading patterns, frameworks with RSC/data). Pair with `lazy()` for code-splitting and error boundaries for failures.

## 🔧 Core concepts [#-core-concepts]

* **Boundary** — catches “suspend” from descendants; shows `fallback`.
* **`React.lazy`** — dynamic `import()` wrapped component.
* **Nested** — nearest boundary handles the suspend.
* **Transitions** — pending transitions can avoid hiding already-shown UI (concurrent).
* **Not for** — ordinary `useEffect` fetching unless integrated with a Suspense-aware data API.

## 💡 Examples [#-examples]

```tsx
import { lazy, Suspense } from "react";

const Editor = lazy(() => import("./Editor"));

export function Page() {
  return (
    <Suspense fallback={<p>Loading editor…</p>}>
      <Editor />
    </Suspense>
  );
}
```

**Nested boundaries:**

```tsx
<Suspense fallback={<PageSkeleton />}>
  <Header />
  <Suspense fallback={<FeedSkeleton />}>
    <Feed />
  </Suspense>
</Suspense>
```

**Named export lazy:**

```tsx
const Chart = lazy(() =>
  import("./Chart").then((m) => ({ default: m.Chart })),
);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Missing error boundary—load failures are not Suspense.
* One giant boundary → whole page flashes fallback.
* Suspense for data without a compatible library/framework → won’t suspend.
* Forgetting a default export when using `lazy(() => import(...))`.

## 🔗 Related [#-related]

* [error\_boundaries.md](/docs/react/error-boundaries) — failures
* [concurrent.md](/docs/react/concurrent) — concurrent UI
* [useTransition.md](/docs/react/usetransition) — pending states
* [performance.md](/docs/react/performance) — code splitting
* [router.md](/docs/react/router) — route-level lazy


---

# Tag (/docs/react/tag)



# Tag [#tag]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

In JSX, **tags** are either host elements (`div`, `span`, `input`) or custom components (`<Button />`). Capitalization decides which.

## 🔧 Core concepts [#-core-concepts]

* **Host tags** — lowercase → DOM/SVG elements.
* **Component tags** — Uppercase → your function/class components.
* **Dynamic tags** — assign to a capitalized variable: `const Tag = as; return <Tag />`.
* **Fragments** — `&lt;>...&lt;/>` or `<Fragment>` with optional `key`.

## 💡 Examples [#-examples]

```tsx
type BoxProps = {
  as?: "div" | "section" | "article";
  children: React.ReactNode;
};

export function Box({ as: Tag = "div", children }: BoxProps) {
  return <Tag className="box">{children}</Tag>;
}
```

```jsx
const ok = true;
return ok ? <span>Yes</span> : <span>No</span>;
```

## ⚠️ Pitfalls [#️-pitfalls]

* `<button>` vs `<Button>` — wrong case mounts the wrong thing.
* Variable component must be capitalized: `const Comp = map[type]` then `<Comp />`.
* Unknown HTML attributes may land on the DOM; filter props for wrappers.

## 🔗 Related [#-related]

* [jsx.md](/docs/react/jsx) — JSX syntax
* [component.md](/docs/react/component) — custom tags
* [tsx.md](/docs/react/tsx) — typed elements
* [children.md](/docs/react/children) — tag children


---

# Testing (/docs/react/testing)



# Testing [#testing]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

Test React components with **React Testing Library** (RTL) + **Vitest/Jest**: assert what users see and do, not implementation details. Use `userEvent` for interactions; mock network at the boundary. Prefer integration-style tests over shallow enzyme-style tests.

## 🔧 Core concepts [#-core-concepts]

| Tool                    | Role                     |
| ----------------------- | ------------------------ |
| `render`                | Mount into jsdom/browser |
| `screen`                | Queries (`getByRole`, …) |
| `userEvent`             | Realistic interactions   |
| `waitFor` / `findBy*`   | Async UI                 |
| `vi.mock` / `jest.mock` | Module mocks             |
| MSW                     | HTTP mocking             |

Query priority: role → label → text → test id (last resort).

## 💡 Examples [#-examples]

```tsx
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { Counter } from "./Counter";

test("increments count", async () => {
  const user = userEvent.setup();
  render(<Counter />);
  await user.click(screen.getByRole("button", { name: /increment/i }));
  expect(screen.getByText("1")).toBeInTheDocument();
});
```

**Async:**

```tsx
render(<UserProfile id="1" />);
expect(await screen.findByRole("heading", { name: /ada/i })).toBeVisible();
```

**Router wrapper:**

```tsx
import { MemoryRouter } from "react-router-dom";

render(
  <MemoryRouter initialEntries={["/posts/1"]}>
    <App />
  </MemoryRouter>,
);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Testing class names / state variables instead of behavior.
* Not wrapping providers (router, theme, query client).
* Forgetting `await` on `userEvent` / `findBy`.
* Snapshot-only tests that churn on markup noise.
* Leaving timers/network open—use fake timers or MSW cleanup.

## 🔗 Related [#-related]

* [hooks.md](/docs/react/hooks) — test via components
* [custom\_hooks.md](/docs/react/custom-hooks) — `renderHook`
* [router.md](/docs/react/router) — MemoryRouter
* [forms.md](/docs/react/forms) — form interactions
* [error\_boundaries.md](/docs/react/error-boundaries) — error UI


---

# Thinking in React (/docs/react/thinking-in-react)



# Thinking in React [#thinking-in-react]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

“Thinking in React” is a design approach: break the UI into a component hierarchy, decide what is state vs props, and let data flow downward. Build static UI first, then add interactivity.

## 🔧 Core concepts [#-core-concepts]

| Step                | What you do                            |
| ------------------- | -------------------------------------- |
| 1. Mock / sketch    | Know the screens and pieces            |
| 2. Split components | One responsibility per component       |
| 3. Static version   | Render with hard-coded props/data      |
| 4. Find state       | What changes over time? Minimize it    |
| 5. Place state      | Own state in the closest common parent |
| 6. Data flow        | Props down; events up                  |

If two components need the same changing data, lift state to their parent.

## 💡 Examples [#-examples]

**Component split (static):**

```jsx
function SearchBar({ query }) {
  return <input value={query} readOnly />;
}

function ProductList({ products }) {
  return (
    <ul>
      {products.map((p) => (
        <li key={p.id}>{p.name}</li>
      ))}
    </ul>
  );
}

function FilterableList({ products }) {
  return (
    <>
      <SearchBar query="" />
      <ProductList products={products} />
    </>
  );
}
```

**Add state in the parent:**

```jsx
import { useState } from "react";

function FilterableList({ products }) {
  const [query, setQuery] = useState("");
  const filtered = products.filter((p) =>
    p.name.toLowerCase().includes(query.toLowerCase())
  );

  return (
    <>
      <input
        value={query}
        onChange={(e) => setQuery(e.target.value)}
        placeholder="Search"
      />
      <ProductList products={filtered} />
    </>
  );
}
```

**Props down, events up:**

```jsx
function SearchBar({ query, onQueryChange }) {
  return (
    <input
      value={query}
      onChange={(e) => onQueryChange(e.target.value)}
    />
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Duplicating the same state in two places causes them to drift.
* Derivable values (filtered lists) usually should not be stored as separate state.
* Giant “god components” are hard to change — split earlier than you think.
* Don’t fetch in every tiny child — load data near the top or in a dedicated module.

## 🔗 Related [#-related]

* [getting\_started.md](/docs/react/getting-started)
* [hello\_world.md](/docs/react/hello-world)
* [keys\_lists.md](/docs/react/keys-lists)
* [conditional\_rendering.md](/docs/react/conditional-rendering)


---

# TSX (/docs/react/tsx)



# TSX [#tsx]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`.tsx` is TypeScript + JSX. Type props, events, and refs for safer components. Use `react` types (`ReactNode`, `CSSProperties`, form events).

## 🔧 Core concepts [#-core-concepts]

* **Props types** — `type Props = \{ ... \}` or `interface`.
* **FC** — prefer explicit props + return; `React.FC` is optional and adds `children` quirks in older typings.
* **Events** — `React.ChangeEvent<HTMLInputElement>`, `React.MouseEvent`.
* **Refs** — `useRef<HTMLDivElement>(null)`.
* **Generics** — `function List<T>(\{ items \}: \{ items: T[] \})`.

## 💡 Examples [#-examples]

```tsx
import { useRef, useState, type FormEvent } from "react";

type FormProps = {
  onSave: (name: string) => void;
};

export function NameForm({ onSave }: FormProps) {
  const [name, setName] = useState("");
  const inputRef = useRef<HTMLInputElement>(null);

  function handleSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    onSave(name);
    inputRef.current?.focus();
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        ref={inputRef}
        value={name}
        onChange={(e) => setName(e.target.value)}
      />
      <button type="submit">Save</button>
    </form>
  );
}
```

```tsx
type ListProps<T> = {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
};

export function List<T>({ items, renderItem }: ListProps<T>) {
  return <ul>{items.map((item, i) => <li key={i}>{renderItem(item)}</li>)}</ul>;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Typing `children` only when needed — don’t force it on every component.
* `as any` on props hides real bugs.
* Ensure `"jsx": "react-jsx"` (or compatible) in `tsconfig`.

## 🔗 Related [#-related]

* [jsx.md](/docs/react/jsx) — JSX without types
* [props.md](/docs/react/props) — prop shapes
* [component.md](/docs/react/component) — components
* [import\_export.md](/docs/react/import-export) — `import type`


---

# useCallback (/docs/react/usecallback)



# useCallback [#usecallback]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useCallback(fn, deps)` returns a memoized function identity until dependencies change. Useful when passing callbacks to memoized children, effect deps, or libraries that compare by reference.

## 🔧 Core concepts [#-core-concepts]

* **Identity** — same function reference across renders if deps unchanged.
* **Pair with `memo`** — child skips re-render if props are equal.
* **Effect deps** — stable callbacks avoid effect churn.
* **Not free** — only when measured or required by API contracts.

## 💡 Examples [#-examples]

```tsx
import { memo, useCallback, useState } from "react";

const Row = memo(function Row({
  id,
  onSelect,
}: {
  id: string;
  onSelect: (id: string) => void;
}) {
  return (
    <button type="button" onClick={() => onSelect(id)}>
      {id}
    </button>
  );
});

export function List({ ids }: { ids: string[] }) {
  const [selected, setSelected] = useState<string | null>(null);
  const onSelect = useCallback((id: string) => setSelected(id), []);

  return (
    <div>
      {ids.map((id) => (
        <Row key={id} id={id} onSelect={onSelect} />
      ))}
      <p>Selected: {selected}</p>
    </div>
  );
}
```

**Functional updates avoid deps:**

```tsx
const increment = useCallback(() => setCount((c) => c + 1), []);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Wrapping every function “just in case”.
* Omitting deps that the callback closes over → stale closures.
* Expecting `useCallback` alone to prevent re-renders—child must be `memo` (or equivalent).
* Putting unstable objects in deps.

## 🔗 Related [#-related]

* [useMemo.md](/docs/react/usememo) — value memoization
* [memo.md](/docs/react/memo) — pure components
* [useEffect.md](/docs/react/useeffect) — dependency arrays
* [performance.md](/docs/react/performance) — profiling
* [hooks.md](/docs/react/hooks) — rules


---

# useContext (/docs/react/usecontext)



# useContext [#usecontext]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useContext(MyContext)` reads the nearest `MyContext.Provider` value and re-renders when that value changes. Prefer context for cross-tree data (theme, auth, locale)—not for high-frequency updates that should stay local or use a store.

## 🔧 Core concepts [#-core-concepts]

* **Create** — `const Ctx = createContext(defaultValue)`.
* **Provide** — `<Ctx.Provider value=\{...\}>`.
* **Consume** — `const value = useContext(Ctx)`.
* **Default** — used only when no Provider is above.
* **Bail out** — same `Object.is` value skips re-render (React 19 / compiler may help further).

## 💡 Examples [#-examples]

```tsx
import { createContext, useContext, useState, type ReactNode } from "react";

type Theme = "light" | "dark";
const ThemeContext = createContext<Theme>("light");

export function ThemeProvider({ children }: { children: ReactNode }) {
  const [theme, setTheme] = useState<Theme>("light");
  return (
    <ThemeContext.Provider value={theme}>
      <button type="button" onClick={() => setTheme((t) => (t === "light" ? "dark" : "light"))}>
        Toggle
      </button>
      {children}
    </ThemeContext.Provider>
  );
}

export function ThemedBox() {
  const theme = useContext(ThemeContext);
  return <div data-theme={theme}>Hello</div>;
}
```

**Split value + setter to limit re-renders:**

```tsx
const ThemeValueCtx = createContext<Theme>("light");
const ThemeSetCtx = createContext<(t: Theme) => void>(() => {});
```

## ⚠️ Pitfalls [#️-pitfalls]

* New object/array in `value=\{\{ theme, setTheme \}\}` every render → all consumers re-render; memoize or split contexts.
* Using context as a global Redux replacement for rapidly changing data.
* Reading context in a parent that doesn’t need it—push consumers down.
* Forgetting a Provider in tests/stories.

## 🔗 Related [#-related]

* [context.md](/docs/react/context) — Provider patterns
* [hooks.md](/docs/react/hooks) — rules of hooks
* [useMemo.md](/docs/react/usememo) — stabilize values
* [performance.md](/docs/react/performance) — re-render control
* [custom\_hooks.md](/docs/react/custom-hooks) — `useTheme()` wrappers


---

# useDeferredValue (/docs/react/usedeferredvalue)



# useDeferredValue [#usedeferredvalue]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useDeferredValue(value)` returns a deferred version of `value` that may “lag behind” during urgent updates. Keep showing the latest input while expensive children render with the deferred value.

## 🔧 Core concepts [#-core-concepts]

* **Lagging copy** — UI can show `value` immediately and `deferred` for heavy work.
* **vs useTransition** — defer a prop/value vs wrap a state update.
* **Concurrent** — React may interrupt rendering the deferred tree.
* **Pending UX** — compare `value !== deferred` to show a stale indicator.

## 💡 Examples [#-examples]

```tsx
import { useDeferredValue, useMemo, useState } from "react";

function SlowList({ query }: { query: string }) {
  const items = useMemo(() => {
    // expensive filter/render
    return Array.from({ length: 5000 }, (_, i) => `${query}-${i}`);
  }, [query]);
  return (
    <ul>
      {items.map((item) => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

export function SearchPage() {
  const [query, setQuery] = useState("");
  const deferredQuery = useDeferredValue(query);
  const isStale = query !== deferredQuery;

  return (
    <div>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <div style={{ opacity: isStale ? 0.6 : 1 }}>
        <SlowList query={deferredQuery} />
      </div>
    </div>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Deferring values that must stay in sync for correctness (validation, submit payload).
* Using as a substitute for debouncing network requests—still debounce fetches.
* Memoizing children incorrectly so deferred updates don’t help.
* Ignoring stale UI—users may click outdated rows; disable or mark pending.

## 🔗 Related [#-related]

* [useTransition.md](/docs/react/usetransition) — startTransition
* [concurrent.md](/docs/react/concurrent) — concurrent rendering
* [performance.md](/docs/react/performance) — optimization
* [memo.md](/docs/react/memo) — skip re-renders
* [hooks.md](/docs/react/hooks) — rules


---

# useEffect (/docs/react/useeffect)



# useEffect [#useeffect]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useEffect` runs **side effects** after paint: subscriptions, network calls, DOM sync, timers. Declare dependencies so effects re-run when values change; return a cleanup function.

## 🔧 Core concepts [#-core-concepts]

* **Signature** — `useEffect(setup, deps?)`.
* **Deps** — `[]` mount/unmount only; omit = every render (rare); list values used inside.
* **Cleanup** — return `() => \{ ... \}` to unsubscribe / clear timers.
* **Strict Mode** — React 18+ remounts once in dev to test cleanup.
* **Prefer** — event handlers or data libraries when an “effect” is really a user action.

## 💡 Examples [#-examples]

```tsx
import { useEffect, useState } from "react";

export function User({ id }: { id: string }) {
  const [user, setUser] = useState<{ name: string } | null>(null);

  useEffect(() => {
    const ctrl = new AbortController();
    fetch(`/api/users/${id}`, { signal: ctrl.signal })
      .then((r) => r.json())
      .then(setUser)
      .catch((err) => {
        if (err.name !== "AbortError") console.error(err);
      });
    return () => ctrl.abort();
  }, [id]);

  if (!user) return <p>Loading…</p>;
  return <p>{user.name}</p>;
}
```

```tsx
useEffect(() => {
  const onResize = () => setWidth(window.innerWidth);
  window.addEventListener("resize", onResize);
  return () => window.removeEventListener("resize", onResize);
}, []);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Missing deps → stale closures; exhaustive-deps lint is your friend.
* Setting state in effects without guards can loop.
* Don’t use effects to transform data for render — compute during render instead.
* Fetch races: abort or ignore outdated responses when `id` changes.

## 🔗 Related [#-related]

* [hooks.md](/docs/react/hooks) — hooks rules
* [useState.md](/docs/react/usestate) — state updates from effects
* [component.md](/docs/react/component) — function components
* [render.md](/docs/react/render) — keep render pure


---

# useId (/docs/react/useid)



# useId [#useid]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useId()` generates a unique, stable ID string per component instance—safe for SSR hydration. Use to link labels and inputs (`htmlFor` / `id`) or ARIA attributes. Do not use as a list `key`.

## 🔧 Core concepts [#-core-concepts]

* **Stable** — same ID across re-renders for that instance.
* **SSR-safe** — matches server and client trees when structure matches.
* **Prefix** — React may prefix (`:r1:`)—valid in HTML `id` / `htmlFor`.
* **Multiple** — call once and suffix (`$\{id\}-name`, `$\{id\}-email`) for related fields.

## 💡 Examples [#-examples]

```tsx
import { useId } from "react";

export function NameField() {
  const id = useId();
  return (
    <div>
      <label htmlFor={id}>Name</label>
      <input id={id} name="name" />
    </div>
  );
}
```

**Shared base for several controls:**

```tsx
function PasswordFields() {
  const id = useId();
  return (
    <>
      <label htmlFor={`${id}-pw`}>Password</label>
      <input id={`${id}-pw`} type="password" aria-describedby={`${id}-hint`} />
      <p id={`${id}-hint`}>At least 8 characters</p>
    </>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using `useId` as React `key`—keys must come from data identity.
* Generating IDs with `Math.random()` / incrementing counters → hydration mismatches.
* Calling different numbers of `useId` on server vs client.
* Assuming format of the string—treat as opaque.

## 🔗 Related [#-related]

* [forms.md](/docs/react/forms) — accessible forms
* [hooks.md](/docs/react/hooks) — rules
* [jsx.md](/docs/react/jsx) — attributes
* [strict\_mode.md](/docs/react/strict-mode) — double-invoke in dev
* [testing.md](/docs/react/testing) — queries by label


---

# useLayoutEffect (/docs/react/uselayouteffect)



# useLayoutEffect [#uselayouteffect]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useLayoutEffect` runs synchronously after DOM mutations but before the browser paints. Use for measuring layout (`getBoundingClientRect`) and applying DOM corrections that must not flicker. Prefer `useEffect` for most subscriptions and data loading.

## 🔧 Core concepts [#-core-concepts]

* **Timing** — render → DOM update → layout effects → paint → passive effects.
* **Same API** — `useLayoutEffect(setup, deps)` like `useEffect`.
* **SSR** — warns on server; gate with `typeof window` or use `useEffect`.
* **Blocking** — long work delays paint—keep short.

## 💡 Examples [#-examples]

```tsx
import { useLayoutEffect, useRef, useState } from "react";

export function Tooltip({ text }: { text: string }) {
  const ref = useRef<HTMLDivElement>(null);
  const [height, setHeight] = useState(0);

  useLayoutEffect(() => {
    const node = ref.current;
    if (!node) return;
    setHeight(node.getBoundingClientRect().height);
  }, [text]);

  return (
    <div ref={ref} style={{ marginTop: height > 40 ? 8 : 0 }}>
      {text}
    </div>
  );
}
```

**Scroll restore without flash:**

```tsx
useLayoutEffect(() => {
  listRef.current?.scrollTo(0, savedScrollTop);
}, [items]);
```

## ⚠️ Pitfalls [#️-pitfalls]

* Using layout effects for data fetching—blocks paint; use `useEffect` / loaders.
* Infinite loops: layout effect sets state that changes layout deps every time.
* SSR mismatch / warnings—prefer `useEffect` unless measurement is required.
* Heavy computation in layout effect → jank.

## 🔗 Related [#-related]

* [useEffect.md](/docs/react/useeffect) — default effect
* [useRef.md](/docs/react/useref) — DOM refs
* [performance.md](/docs/react/performance) — paint timing
* [hooks.md](/docs/react/hooks) — rules
* [concurrent.md](/docs/react/concurrent) — rendering model


---

# useMemo (/docs/react/usememo)



# useMemo [#usememo]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useMemo(() => compute(a, b), [a, b])` caches a computed value until dependencies change. Use for expensive pure calculations or to keep referential equality for children/context—not as a default optimization.

## 🔧 Core concepts [#-core-concepts]

* **Signature** — `const memo = useMemo(factory, deps)`.
* **Deps** — recompute when any dep fails `Object.is`.
* **React 19 / Compiler** — compiler may memoize automatically; manual useMemo still valid for guarantees.
* **vs useCallback** — memoize value vs memoize function (`useCallback(fn, deps)` ≈ `useMemo(() => fn, deps)`).

## 💡 Examples [#-examples]

```tsx
import { useMemo, useState } from "react";

export function FilteredList({ items, query }: { items: string[]; query: string }) {
  const filtered = useMemo(() => {
    const q = query.trim().toLowerCase();
    return items.filter((item) => item.toLowerCase().includes(q));
  }, [items, query]);

  return (
    <ul>
      {filtered.map((item) => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}
```

**Stable context value:**

```tsx
const value = useMemo(() => ({ user, logout }), [user, logout]);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
```

## ⚠️ Pitfalls [#️-pitfalls]

* Memoizing cheap work—overhead can exceed savings.
* Missing deps → stale values; extra deps → useless recomputes.
* Mutating the memoized object/array in place.
* Using `useMemo` to “hide” side effects—factory must be pure.

## 🔗 Related [#-related]

* [useCallback.md](/docs/react/usecallback) — function identity
* [memo.md](/docs/react/memo) — skip child re-renders
* [performance.md](/docs/react/performance) — when to optimize
* [useContext.md](/docs/react/usecontext) — stable provider values
* [hooks.md](/docs/react/hooks) — rules


---

# useReducer (/docs/react/usereducer)



# useReducer [#usereducer]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useReducer(reducer, initialState)` manages state with a `(state, action) => nextState` function. Prefer when updates are complex, multi-field, or easier to test as pure transitions than scattered `setState` calls.

## 🔧 Core concepts [#-core-concepts]

* **Reducer** — pure; no side effects.
* **Dispatch** — stable identity; `dispatch(action)`.
* **Init** — `useReducer(reducer, initArg, init)` for lazy setup.
* **vs useState** — state for simple values; reducer for structured transitions.
* **Actions** — discriminated unions in TypeScript.

## 💡 Examples [#-examples]

```tsx
import { useReducer } from "react";

type State = { count: number; step: number };
type Action =
  | { type: "increment" }
  | { type: "decrement" }
  | { type: "setStep"; step: number }
  | { type: "reset" };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case "increment":
      return { ...state, count: state.count + state.step };
    case "decrement":
      return { ...state, count: state.count - state.step };
    case "setStep":
      return { ...state, step: action.step };
    case "reset":
      return { count: 0, step: 1 };
    default:
      return state;
  }
}

export function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 });
  return (
    <div>
      <p>{state.count}</p>
      <button type="button" onClick={() => dispatch({ type: "increment" })}>
        +
      </button>
      <button type="button" onClick={() => dispatch({ type: "setStep", step: 5 })}>
        step 5
      </button>
    </div>
  );
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Side effects inside reducers (fetch, DOM)—put in effects or event handlers.
* Mutating `state` instead of returning a new object.
* Overusing for a single boolean toggle.
* Forgetting exhaustive `switch` handling in TS.

## 🔗 Related [#-related]

* [useState.md](/docs/react/usestate) — simpler state
* [hooks.md](/docs/react/hooks) — rules
* [context.md](/docs/react/context) — dispatch via context
* [testing.md](/docs/react/testing) — pure reducer tests
* [performance.md](/docs/react/performance) — update patterns


---

# useRef (/docs/react/useref)



# useRef [#useref]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useRef(initial)` returns a stable `\{ current \}` box that persists across renders without causing re-renders when mutated. Use for DOM nodes, timer IDs, previous values, and imperative handles—not for UI state.

## 🔧 Core concepts [#-core-concepts]

* **Mutable box** — `ref.current = x` does not trigger render.
* **DOM refs** — `ref=\{elRef\}` on host components; read after commit.
* **Same identity** — ref object is stable for the component lifetime.
* **vs state** — state → re-render; ref → silent store.
* **Callback refs** — function form when you need attach/detach logic.

## 💡 Examples [#-examples]

```tsx
import { useEffect, useRef } from "react";

export function TextField() {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return <input ref={inputRef} />;
}
```

**Previous value / interval:**

```tsx
function usePrevious<T>(value: T) {
  const ref = useRef<T>(undefined);
  useEffect(() => {
    ref.current = value;
  }, [value]);
  return ref.current;
}

function Ticker() {
  const idRef = useRef<number | null>(null);
  useEffect(() => {
    idRef.current = window.setInterval(() => {}, 1000);
    return () => {
      if (idRef.current != null) window.clearInterval(idRef.current);
    };
  }, []);
  return null;
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* Reading/writing `ref.current` during render for values that drive UI—use state.
* Assuming ref is set during first render of a child—refs populate after commit.
* Storing JSX in refs instead of state.
* Forgetting to clear timers/subscriptions stored on refs.

## 🔗 Related [#-related]

* [useEffect.md](/docs/react/useeffect) — sync after paint
* [forwardRef.md](/docs/react/forwardref) — expose refs to parents
* [useLayoutEffect.md](/docs/react/uselayouteffect) — measure DOM before paint
* [hooks.md](/docs/react/hooks) — hook rules
* [forms.md](/docs/react/forms) — uncontrolled inputs


---

# useState (/docs/react/usestate)



# useState [#usestate]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useState` adds local state to a function component. Calling the setter queues a re-render with the new value.

## 🔧 Core concepts [#-core-concepts]

* **Signature** — `const [state, setState] = useState(initial)`.
* **Lazy init** — `useState(() => expensive())` runs once.
* **Updater form** — `setState(prev => next)` when next depends on previous.
* **Objects/arrays** — replace immutably; don’t mutate then set the same reference.
* **Batching** — React batches updates in event handlers (and more in React 18+).

## 💡 Examples [#-examples]

```tsx
import { useState } from "react";

export function Counter() {
  const [count, setCount] = useState(0);
  return (
    <button type="button" onClick={() => setCount((c) => c + 1)}>
      {count}
    </button>
  );
}
```

```tsx
type Todo = { id: string; text: string; done: boolean };

export function TodoDraft() {
  const [todos, setTodos] = useState<Todo[]>([]);

  function add(text: string) {
    setTodos((prev) => [
      ...prev,
      { id: crypto.randomUUID(), text, done: false },
    ]);
  }

  function toggle(id: string) {
    setTodos((prev) =>
      prev.map((t) => (t.id === id ? { ...t, done: !t.done } : t)),
    );
  }

  return null; // wire UI as needed
}
```

## ⚠️ Pitfalls [#️-pitfalls]

* `setState(obj.x++)` / mutating then `setState(obj)` — React may skip the update.
* Using state as the only source when you could derive: `const full = first + last`.
* Storing props in state without a sync strategy → stale UI.
* For complex transitions prefer `useReducer`.

## 🔗 Related [#-related]

* [hooks.md](/docs/react/hooks) — hooks overview
* [useEffect.md](/docs/react/useeffect) — syncing with external systems
* [events.md](/docs/react/events) — updating from handlers
* [props.md](/docs/react/props) — vs lifting state


---

# useTransition (/docs/react/usetransition)



# useTransition [#usetransition]

*React · Reference cheat sheet*

***

## 📋 Overview [#-overview]

`useTransition` marks state updates as non-urgent so React can keep the UI responsive. Returns `[isPending, startTransition]`. Use for heavy re-renders (filtering large lists, tab switches) while keeping input snappy.

## 🔧 Core concepts [#-core-concepts]

* **Urgent vs transition** — typing stays urgent; list filter can be a transition.
* **`startTransition(fn)`** — wrap the `setState` that triggers expensive UI.
* **`isPending`** — true while the transition is in progress.
* **`useDeferredValue`** — alternative when you defer a value instead of an update.
* **Concurrent** — requires concurrent features (React 18+).

## 💡 Examples [#-examples]

```tsx
import { useState, useTransition } from "react";

export function Search({ items }: { items: string[] }) {
  const [query, setQuery] = useState("");
  const [list, setList] = useState(items);
  const [isPending, startTransition] = useTransition();

  function onChange(e: React.ChangeEvent<HTMLInputElement>) {
    const value = e.target.value;
    setQuery(value); // urgent: update input
    startTransition(() => {
      setList(items.filter((item) => item.includes(value)));
    });
  }

  return (
    <div>
      <input value={query} onChange={onChange} />
      {isPending ? <p>Updating…</p> : null}
      <ul>
        {list.map((item) => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}
```

**Navigation-style:**

```tsx
startTransition(() => setTab("photos"));
```

## ⚠️ Pitfalls [#️-pitfalls]

* Wrapping controlled input updates in `startTransition` → laggy typing.
* Side effects inside transitions that assume immediate commit.
* Expecting transitions to cancel fetches—pair with AbortController / effects carefully.
* Nested transitions without understanding pending boundaries.

## 🔗 Related [#-related]

* [useDeferredValue.md](/docs/react/usedeferredvalue) — defer a value
* [concurrent.md](/docs/react/concurrent) — concurrent model
* [suspense.md](/docs/react/suspense) — pending UI
* [performance.md](/docs/react/performance) — responsiveness
* [hooks.md](/docs/react/hooks) — rules

