Skip to content
Back to skills

State Management

ASecurity

Best practices for managing state (Server URL vs Client Hooks).

  • 8 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 8, 2026
ai-agentsgonextjsapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 8, 2026

npx -y skills add ngxtm/devkit --skill state-management --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of State Management?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for State Management
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ngxtm-state-management/badge)](https://www.skillsdirectory.com/skills/ngxtm-state-management)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Next.js State Management
description: Best practices for managing state (Server URL vs Client Hooks).
metadata:
  labels: [nextjs, state, zustand, context]
  triggers:
    files: ['**/hooks/*.ts', '**/store.ts', '**/components/*.tsx']
    keywords: [useState, useContext, zustand, redux]
---

# State Management

## **Priority: P2 (MEDIUM)**

Prefer Server State (URL) and Local State over Global Stores.

## Principles

1. **URL as Source of Truth**: For any state that should be shareable or persistent (Search queries, Filters, Pagination, Tabs), use the URL Search Params.
   - _Why_: Keeps state syncable across refreshes and shareable links.
   - _Tool_: `useSearchParams` hook.
2. **Colocation**: Keep state as close to the component as possible. **Do not lift state** unless necessary to share between siblings.
   - _Bad_: `App` component holding `searchTerm` for a `SearchBar` nested 5 levels deep.
   - _Good_: `SearchBar` has internal state, or `MainContent` holds it if it needs to pass to siblings.
3. **No Global Store Default**: Avoid Redux/Zustand for simple apps. Be skeptical of adding a library.
   - _Use Cases for Global Store_: Complex interactors like a Music Player (persists across navigation), Shopping Cart (shared everywhere).

## Patterns

### 1. Granular State (Best Practice)

Don't store large objects. Subscribe only to what you need to prevent unnecessary re-renders.

```tsx
// BAD: Re-renders on any change to 'user'
const [user, setUser] = useState({ name: '', stats: {}, friends: [] });

// GOOD: Independent states
const [name, setName] = useState('');
const [stats, setStats] = useState({});
```

### 2. URL-Driven State (Search/Filter)

```tsx
// Client Component
'use client';
import { useSearchParams, useRouter, usePathname } from 'next/navigation';

export function Search() {
  const searchParams = useSearchParams();
  const { replace } = useRouter();
  const pathname = usePathname();

  function handleSearch(term: string) {
    const params = new URLSearchParams(searchParams);
    if (term) params.set('q', term);
    else params.delete('q');

    // Updates URL -> Server Component re-renders with new params
    replace(`${pathname}?${params.toString()}`);
  }
}
```

### 3. Server State (TanStack Query / SWR)

If you need "Live" data on the client (e.g., polling stock prices, chat), do not implement `useEffect` fetch manually. Use a library.

```tsx
// Automated caching, deduplication, and revalidation
const { data, error } = useSWR('/api/user', fetcher);
```

Files in this skill

  • SKILL.md2.5 KB
  • references/REFERENCE.md380 B
  • references/state-patterns.md5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…