← ClaudeAtlas

react-18-noteslisted

React 18 (March 2022) signature features and the migration traps from 17 -> 18. Use when writing or reviewing code in a React 18 project, or a package whose package.json constraint is ^18 (or ^18.2). Covers createRoot/hydrateRoot, automatic batching, the opt-in concurrent features (startTransition/useTransition/useDeferredValue), streaming SSR (renderToPipeableStream), the new hooks (useId/useSyncExternalStore/useInsertionEffect), and StrictMode effect double-invocation. Not for application business logic — load when working on React root setup, concurrent-rendering code, or planning a 17 -> 18 (or 18 -> 19) upgrade. Pairs cross-stack with the nextjs modules; React 18.2+ is the floor Next.js 16 supports. Output: version-specific guidance, migration traps, and verification gates.
hmj1026/dhpk · ★ 2 · Web & Frontend · score 68
Install: claude install-skill hmj1026/dhpk
# React 18 — concurrent-rendering baseline React 18 (March 2022) shipped the concurrent renderer. Its features are opt-in per update, unlocked by adopting the new `createRoot` API. > Floor role: **React 18.2.0+** is the minimum Next.js 16 supports and one > side of Next.js 15.5's React 18/19 dual support. This module is the > standalone home for React-language guidance — pair it cross-stack with a > `nextjs-<version>` module, or use it for any non-Next React app. --- ## Signature features ### `createRoot` / `hydrateRoot` (react-dom/client) The new root API replaces `ReactDOM.render` and is what turns on all React 18 features. `ReactDOM.render` still works but warns and runs in a legacy (non-concurrent) mode. ```js // Before (React 17) import { render } from 'react-dom' render(<App />, document.getElementById('root')) // React 18 import { createRoot } from 'react-dom/client' const root = createRoot(document.getElementById('root')) root.render(<App />) ``` SSR hydration moves from `ReactDOM.hydrate` to `hydrateRoot`. ### Automatic batching All state updates are now batched — including those inside promises, `setTimeout`, and native event handlers, not just React event handlers. Force a synchronous flush with `flushSync` when a DOM read must happen between updates. ```js setTimeout(() => { setCount(c => c + 1) setFlag(f => !f) // React 18: one re-render (batched); React 17: two re-renders }, 1000) ``` ### Concurrent features (opt-in) Enabled per update, not g