Foundations: useState — what is it used for?
Adds local component state.setState schedules the next render (state is a per-render snapshot).
Use for UI/local state (inputs, toggles, selection).
Foundations: useState — when NOT to use it?
Don’t store derived state (compute from props/state).
Complex transitions → useReducer.
Server data/caching → a cache layer (e.g., React Query).
Foundations: useState — top gotchas evaluators flag
setState.Foundations: useState — canonical TS patterns
Type when needed: useState<T | null>(null).
Prev-based: setN(n => n + 1).
Lazy init: useState(() => expensiveInit()).
Foundations: useReducer — what is it used for?
State via a reducer: dispatch(action) computes next state.
Use for complex transitions / multiple related fields.
Improves predictability vs many useStates.
Foundations: useReducer — when NOT to use it?
Don’t use for simple scalar UI state (prefer useState).
Don’t put async side effects in the reducer (keep reducer pure).
Server state still belongs in a cache layer.
Foundations: useReducer — gotchas evaluators flag
Foundations: useReducer — canonical TS patterns
Prefer discriminated unions for actions.
Reducer signature: (state, action) => nextState.
Initialize with stable initialState (or init function if needed).
Foundations: useEffect — what is it used for?
Runs side effects after render.
Use to sync with external systems (fetch, subscriptions, timers).
Supports cleanup: return () => ....
Foundations: useEffect — dependency array basics
[deps] must include reactive inputs used inside the effect.
Missing deps → stale closure bugs.
Cleanup runs on unmount and before re-run.
Foundations: useEffect — when NOT to use it?
Don’t use effects to compute derived UI state.
Don’t mirror props into state unless you truly need it.
Don’t use effect as a general “run code” bucket (prefer event handlers).
Foundations: useEffect — top gotchas evaluators flag
Foundations: useLayoutEffect — what is it used for?
Like useEffect, but runs before paint after DOM mutations.
Use for measure → write to avoid flicker.
Keep work minimal (can block paint).
Foundations: useLayoutEffect — when NOT to use it?
Prefer useEffect unless you need layout timing.
Avoid heavy work (jank).
Be careful with SSR (may warn if it runs on server).
Foundations: useLayoutEffect — common gotcha
Overuse causes render blocking / jank.
If you’re not measuring layout, it’s usually the wrong tool.
Foundations: useMemo — what is it used for?
Memoizes a computed value.
Recomputes only when deps change.
Use for expensive compute or stable derived objects/arrays.
Foundations: useMemo — when NOT to use it?
Don’t memoize trivial work (overhead > benefit).
Don’t use it as correctness glue for missing deps.
If nothing depends on reference identity, skip it.
Foundations: useMemo — gotchas evaluators flag
Foundations: useCallback — what is it used for?
Memoizes a function identity.
Use when passing callbacks to React.memo children or effect deps.
Helps with referential stability.
Foundations: useCallback — when NOT to use it?
Don’t wrap every handler by default.
If the callback isn’t a dependency and not passed to memoized children, skip it.
Premature optimization can harm readability.
Foundations: useCallback — gotchas evaluators flag
Foundations: useRef — what is it used for?
Persistent mutable container: ref.current survives renders.
Updating it does not rerender.
Use for DOM refs or instance values (timers, previous values).
Foundations: useRef — when NOT to use it?
useRef can cause ghost UI (data changes, screen doesn’t).Foundations: useRef — gotchas evaluators flag