State & effects
Lazy initial state
tsx
const [data, setData] = useState(() => expensiveInit());Effect with cleanup
tsx
useEffect(() => {
const ctrl = new AbortController();
fetch('/api/items', { signal: ctrl.signal })
.then((r) => r.json())
.then(setItems);
return () => ctrl.abort();
}, []);Derived state — don't useState itCompute during render; no effect needed
tsx
const total = items.reduce((n, i) => n + i.price, 0);React 19
useActionState
tsx
const [state, formAction, pending] = useActionState(
async (prev, formData) => save(formData),
null,
);Ref as a propref no longer needs forwardRef
tsx
<Dialog ref={dialogRef} />useOptimistic
tsx
const [optimistic, addOptimistic] = useOptimistic(items, (cur, item) => [...cur, item]);