Functional components are JS functions returning JSX. The modern standard — no class components needed.
Props pass data parent → child. Always read-only — never mutate props directly.
JSX compiles to React.createElement(). Use className not class.
Keys help React identify list items. Use stable unique IDs, never array index.
useState — local reactive state; triggers re-render on every update.
useEffect — side effects after render. Return cleanup fn to avoid memory leaks.
State is async — don't rely on updated value immediately after setter call.
Derived state — compute from existing state; avoid keeping duplicate state in sync.
useContext — consume React context; avoids deeply nested prop drilling.
useRef — mutable ref, no re-render. Great for DOM access & timers.
useMemo — cache expensive computation results between renders.
useCallback — memoize function references to prevent child re-renders.
useReducer — complex state logic with dispatch actions, like a local Redux.
Lifting state — move shared state up to nearest common ancestor.
Controlled inputs — React drives value via state (value + onChange).
Composition — use children prop and slot patterns over inheritance.
Render props / HOCs — older patterns; mostly replaced by custom hooks today.
Next.js — SSR, SSG, App Router, file-based routing. Best for production.
Vite + React — lightning-fast SPA dev setup; modern replacement for CRA.
Remix — full-stack, loader/action model with strong form handling.
React Native — same React logic targeting iOS & Android natively.
Context API — built-in; great for low-frequency updates like theme, auth.
Zustand — minimal, flexible, zero boilerplate. Best for most apps.
Redux Toolkit — structured, predictable; ideal for large teams.
Jotai / Recoil — atomic state model with fine-grained subscriptions.
React.memo — skip re-render if props are shallowly equal.
Lazy + Suspense — code-split with React.lazy(() => import(...)).
Batching — React 18 auto-batches all state updates, even async callbacks.
Transitions — useTransition marks non-urgent UI updates, keeps UI snappy.
Profiler — DevTools Profiler pinpoints slow components with flame graphs.
React Router v6 — declarative routing, nested routes, useNavigate.
TanStack Query — server state, caching, background refetches. De-facto standard.
SWR — Vercel's stale-while-revalidate data fetching library.
Next.js server components — fetch on server, zero client bundle impact.
Never do arr.push(x). React won't detect the change — always return new references.
Use setState([...arr, x]) or setState(prev => [...prev, x]) for safe updates.
Stale closures from empty [] — effect won't re-run. Use ESLint exhaustive-deps rule.
List every variable used inside the effect. Stabilize fns with useCallback.
Causes wrong state after list reorder or insert. React matches by key, not position.
Use item.id from data, or generate with crypto.randomUUID() at creation.
Don't sync state-to-state with effects. Prefer event handlers for user interactions.
Compute in render body. Effects are only for external system sync (APIs, subscriptions).