React Cheatsheet
Every essential React pattern: hooks, props, state, effects, context, performance, and component patterns, with syntax and real use cases.48 commands · 6 sections
React is the most popular UI library for the web. This cheatsheet covers the patterns you write daily: hooks for state, effects, refs, and performance, props and event handling, context and reducers, forms, and the component patterns that scale.
Every entry shows real syntax followed by the use case: when and why you reach for it.
Hooks: State7
const [count, setCount] = useState(0)useState(() => expensiveInit())setCount(c => c + 1)const [user, setUser] = useState<User | null>(null)const [form, setForm] = useState({})
setForm(f => ({ ...f, name }))const [items, setItems] = useState([])
setItems(prev => [...prev, newItem])const [tab, setTab] = useState<"home" | "settings">("home")Hooks: Effects & Refs8
useEffect(() => { }, [deps])useEffect(() => { }, [])useEffect(() => {
return () => cleanup()
}, [])useEffect(() => {
document.title = title
}, [title])const ref = useRef<HTMLDivElement>(null)
ref.current?.focus()const prev = useRef(0)
useEffect(() => { prev.current = count })const idRef = useRef<number>(0)
idRef.current = idRef.current + 1useLayoutEffect(() => { }, [])Hooks: Performance7
const memoized = useMemo(() => compute(a, b), [a, b])const handler = useCallback(() => doSomething(x), [x])const Comp = memo(function Comp({ value }) { })const Lazy = lazy(() => import("./Heavy"))
<Suspense fallback={<Spinner />}><Lazy /></Suspense>const [startTransition] = useTransition()
startTransition(() => setFilter(q))useDeferredValue(value)useId()Hooks: Context & Reducers7
const ThemeCtx = createContext<Theme>(defaultTheme)<ThemeCtx.Provider value={theme}>{children}</ThemeCtx.Provider>const theme = useContext(ThemeCtx)function useTheme() {
const ctx = useContext(ThemeCtx)
if (!ctx) throw new Error("useTheme must be used inside provider")
return ctx
}const [state, dispatch] = useReducer(reducer, initialState)function reducer(state, action) {
switch (action.type) {
case "add": return { ...state, items: [...state.items, action.item] }
case "clear": return { items: [], total: 0 }
}
}useReducer(reducer, null, init)Component Patterns9
function Card({ title, children }: { title: string; children: React.ReactNode })function Button({ variant = "primary", ...rest }: ButtonProps) { }const Avatar = ({ src, name }: AvatarProps) => <img src={src} alt={name} />function Toggle({ on, onToggle }: { on: boolean; onToggle: () => void })function useCounter(initial = 0) {
const [count, setCount] = useState(initial)
return { count, inc: () => setCount(c => c + 1) }
}function List({ items, renderItem }: { items: T[]; renderItem: (item: T) => ReactNode })React.createPortal(child, document.body)class ErrorBoundary extends React.Component {
static getDerivedStateFromError() { return { hasError: true } }
}function App() {
return <ErrorBoundary fallback={<Oops />}><Routes /></ErrorBoundary>
}Forms & Events10
onClick={() => ...}onChange={(e) => setValue(e.target.value)}onSubmit={(e) => { e.preventDefault(); save() }}onKeyDown={(e) => { if (e.key === "Enter") ... }}onChange={(e) => setFiles(Array.from(e.target.files ?? []))}type="checkbox" checked={checked} onChange={e => setChecked(e.target.checked)}onSubmit={async (e) => { e.preventDefault(); setSaving(true); try { await save() } finally { setSaving(false) } }}const formRef = useRef<HTMLFormElement>(null)
formRef.current?.reset()onBlur={() => validate(email)}disabled={!form.name || !form.email}React Cheatsheet
Every essential React pattern: hooks, props, state, effects, context, performance, and component patterns, with syntax and real use cases.
React is the most popular UI library for the web. This cheatsheet covers the patterns you write daily: hooks for state, effects, refs, and performance, props and event handling, context and reducers, forms, and the component patterns that scale.
Every entry shows real syntax followed by the use case: when and why you reach for it.
Hooks: State
const [count, setCount] = useState(0): Local state: re-renders the component on change.useState(() => expensiveInit()): Lazy initializer: runs once, skips expensive work on every render.setCount(c => c + 1): Functional update: safe when the new value depends on the old.const [user, setUser] = useState<User | null>(null): State with a type and initial null: loading states.const [form, setForm] = useState({})
setForm(f => ({ ...f, name })): Update one field of an object state: spread pattern.const [items, setItems] = useState([])
setItems(prev => [...prev, newItem]): Append to array state: immutable update.const [tab, setTab] = useState<"home" | "settings">("home"): Union-typed state: tab switches and modes.Hooks: Effects & Refs
useEffect(() => { }, [deps]): Side effects: fetch, subscriptions, DOM updates. Runs after render.useEffect(() => { }, []): Empty deps: runs once after mount. The mount effect.useEffect(() => {
return () => cleanup()
}, []): Cleanup function: unsubscribe and clear timers on unmount.useEffect(() => {
document.title = title
}, [title]): Sync with the outside world: document, window, storage.const ref = useRef<HTMLDivElement>(null)
ref.current?.focus(): Ref: access DOM nodes imperatively.const prev = useRef(0)
useEffect(() => { prev.current = count }): Track the previous value: compare old vs new.const idRef = useRef<number>(0)
idRef.current = idRef.current + 1: Mutable value that does NOT trigger re-renders: counters, ids.useLayoutEffect(() => { }, []): Runs before paint: measure layout without flicker.Hooks: Performance
const memoized = useMemo(() => compute(a, b), [a, b]): Cache an expensive computation until deps change.const handler = useCallback(() => doSomething(x), [x]): Stable function identity: keeps memoized children from re-rendering.const Comp = memo(function Comp({ value }) { }): React.memo: skip re-renders when props are unchanged.const Lazy = lazy(() => import("./Heavy"))
<Suspense fallback={<Spinner />}><Lazy /></Suspense>: Code splitting: load heavy components on demand.const [startTransition] = useTransition()
startTransition(() => setFilter(q)): Mark updates as non-urgent: keep typing responsive on big lists.useDeferredValue(value): Defer a value's update: stale-but-smooth during heavy renders.useId(): Stable unique id: for labels and aria attributes.Hooks: Context & Reducers
const ThemeCtx = createContext<Theme>(defaultTheme): Create context: share data without prop drilling.<ThemeCtx.Provider value={theme}>{children}</ThemeCtx.Provider>: Provide the value: wrap the tree that needs it.const theme = useContext(ThemeCtx): Consume context in any child.function useTheme() {
const ctx = useContext(ThemeCtx)
if (!ctx) throw new Error("useTheme must be used inside provider")
return ctx
}: Custom hook wrapping context: fail fast, clean API.const [state, dispatch] = useReducer(reducer, initialState): Reducer: complex state transitions as pure functions.function reducer(state, action) {
switch (action.type) {
case "add": return { ...state, items: [...state.items, action.item] }
case "clear": return { items: [], total: 0 }
}
}: Reducer with discriminated actions.useReducer(reducer, null, init): Lazy reducer init: for state derived from props or storage.Component Patterns
function Card({ title, children }: { title: string; children: React.ReactNode }): Props with children: the layout component pattern.function Button({ variant = "primary", ...rest }: ButtonProps) { }: Default props via destructuring + rest spread.const Avatar = ({ src, name }: AvatarProps) => <img src={src} alt={name} />: Stateless function component: pure presentational.function Toggle({ on, onToggle }: { on: boolean; onToggle: () => void }): Controlled component: parent owns the state.function useCounter(initial = 0) {
const [count, setCount] = useState(initial)
return { count, inc: () => setCount(c => c + 1) }
}: Custom hook: reuse stateful logic across components.function List({ items, renderItem }: { items: T[]; renderItem: (item: T) => ReactNode }): Render prop: the caller decides how to render.React.createPortal(child, document.body): Portal: render outside the component tree. Modals and tooltips.class ErrorBoundary extends React.Component {
static getDerivedStateFromError() { return { hasError: true } }
}: Error boundary: catch render errors, show a fallback UI.function App() {
return <ErrorBoundary fallback={<Oops />}><Routes /></ErrorBoundary>
}: Top-level error boundary: the app-level crash guard.Forms & Events
onClick={() => ...}: Click handler: the most common event.onChange={(e) => setValue(e.target.value)}: Controlled input: value from state, update on change.onSubmit={(e) => { e.preventDefault(); save() }}: Form submit: always preventDefault.onKeyDown={(e) => { if (e.key === "Enter") ... }}: Keyboard events: shortcuts and Enter-to-submit.onChange={(e) => setFiles(Array.from(e.target.files ?? []))}: File input: read selected files.type="checkbox" checked={checked} onChange={e => setChecked(e.target.checked)}: Controlled checkbox.onSubmit={async (e) => { e.preventDefault(); setSaving(true); try { await save() } finally { setSaving(false) } }}: Async submit with loading state.const formRef = useRef<HTMLFormElement>(null)
formRef.current?.reset(): Reset a form imperatively.onBlur={() => validate(email)}: Validate on blur: friendly inline errors.disabled={!form.name || !form.email}: Disable submit until valid: simple gating.Frequently asked questions
What is the difference between useState and useReducer?
useState is for simple independent values. useReducer manages complex state transitions with a reducer function and actions: better when updates depend on each other or need testing. Both trigger re-renders on change.
How does the useEffect dependency array work?
The effect runs after render when any dependency changes: [] runs once on mount, [value] runs when value changes, and no array runs after every render. Return a cleanup function for subscriptions and timers.
What is the difference between useEffect and useLayoutEffect?
useLayoutEffect runs synchronously after DOM mutations but before the browser paints: use it to measure layout and avoid visual flicker. useEffect runs after paint and is correct for most cases.
What is React.memo and when should I use it?
React.memo prevents re-renders when props are unchanged. Use it for expensive components that render often with stable props, but not as a default: the comparison itself costs time.