Agent-skills-standard nextjs-state-management
Apply best practices for managing URL, server, and client state in Next.js applications. Use when choosing between URL params, SWR/TanStack Query, Zustand, or Context for state, or when fixing hydration mismatches from localStorage. (triggers: **/hooks/*.ts, **/store.ts, **/components/*.tsx, useState, useContext, zustand, redux)
install
source · Clone the upstream repo
git clone https://github.com/HoangNguyen0403/agent-skills-standard
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/HoangNguyen0403/agent-skills-standard "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/nextjs/nextjs-state-management" ~/.claude/skills/hoangnguyen0403-agent-skills-standard-nextjs-state-management && rm -rf "$T"
manifest:
skills/nextjs/nextjs-state-management/SKILL.mdsource content
State Management
Priority: P2 (MEDIUM)
Decision Guide
- Shareable/persistent? Use URL state (
+useSearchParams
).useRouter - Server data? Use SWR or TanStack Query. Never sync into
.useState - Complex client UI? Use Zustand (in
only) or Jotai.'use client' - Simple local? Use
. Colocate as close to consumer as possible.useState
URL-Driven State
Server State (SWR / TanStack Query)
Client State (Zustand)
Hydration Safety
Wrap
localStorage reads in useEffect or mounted flag to avoid hydration mismatches. Manage optimistic updates with useOptimistic in Next.js 15+.
Legacy Redux (existing projects)
If project already uses
redux@4 + createStore + redux-thunk + next-redux-wrapper:
- Use
/useSelector
hooks — never connect HOC.useDispatch - Define typed
and typedRootState
for all selectors and dispatch calls.AppDispatch - Avoid adding Zustand or TanStack Query on top of existing Redux codebase — migrate incrementally if needed.
- Migration path: Redux Toolkit (
) → RTK Query → then consider TanStack Query.@reduxjs/toolkit
See references/redux.md for typed selector and thunk patterns.
Library Patterns
Anti-Patterns
- No global store for simple state: Use
or URL params; avoid Zustand for basic UI.useState - No large objects in state: Decompose into granular primitives to prevent extra re-renders.
- No
for data fetching: Use SWR or TanStack Query for server state.useEffect - No server state in client stores: Fetch in RSCs; client stores for UI-only state.