К основному содержанию
скилл CX Codex

zustand-state-management — скилл для Claude Code: установка

Задаёт правила архитектуры сторов Zustand в React и TypeScript: от нарезки слайсов до SSR и тестов. Помогает избежать лишних ререндеров и ошибок гидратации.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add Mindrally/skills --skill zustand-state-management -a claude-code
Открыть на GitHub

Что делает zustand-state-management

Скилл внедряет строгие правила проектирования хранилищ Zustand в связке с React и TypeScript. Он запрещает превращать клиентский стор в свалку серверных ответов или держать в нём состояние единичных кнопок. Локальный UI остаётся в useState, а серверные запросы уходят в TanStack Query или SWR. Стор остаётся чистым. Большие хранилища скилл делит на типизированные предметные слайсы, объединяя их на внешней границе.

Особое внимание уделено селекторам. Чтобы исключить повторные рендеры при возврате объектов или кортежей, скилл требует использовать useShallow из zustand/react/shallow. В экшенах запрещены анонимные сеттеры и глубокие мутации без immer. Браузерные токены или пароли сохранять через persist нельзя: чувствительные данные не должны оседать в открытом хранилище браузера.

При работе с Next.js и React Server Components скилл изолирует хранилища. Серверные компоненты не должны читать браузерные сторы. Это предотвращает рассинхронизацию. Для рендеринга на сервере создаются отдельные vanilla-сторы под каждый запрос, что исключает утечку данных между разными пользователями.

Какие задачи решает

  • разделить монолитный стор приложения на типизированные слайсы
  • устранить лишние ререндеры компонентов через селекторы и useShallow
  • настроить persist с миграциями без сохранения токенов в браузер
  • изолировать клиентские сторы от React Server Components и SSR
  • протестировать экшены стора напрямую без рендеринга компонентов

Примеры запросов агенту

  • Спроектируй Zustand-стор для корзины заказов с типизированными экшенами и селектором через useShallow.
  • Настрой сохранение параметров фильтра через persist с миграциями и версионированием.
  • Переведи глобальный стор на изолированные слайсы и напиши модульные тесты для экшенов.

Как установить zustand-state-management

1Через Skills CLI (Vercel)

npx skills add Mindrally/skills --skill zustand-state-management -a claude-code

2Вручную: положить файлы

~/.claude/skills/zustand-state-management/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/zustand-state-management/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о zustand-state-management

Как установить zustand-state-management в Claude Code?

Выполните в терминале команду npx skills add Mindrally/skills --skill zustand-state-management -a claude-code.

Что делает скилл zustand-state-management?

Он задаёт стандарты построения сторов Zustand: типизацию действий, предотвращение ререндеров с useShallow, настройку мидлваров persist и изоляцию состояния при SSR.

Как скилл рекомендует разделять состояние между Zustand и TanStack Query?

Серверные данные должны оставаться в TanStack Query или SWR без дублирования в Zustand. Стор Zustand используется только для клиентского состояния, разделяемого независимыми компонентами.

Исходный текст

SKILL.md · Apache-2.0
---
name: zustand-state-management
description: "Best practices for Zustand state management in React and TypeScript applications, covering store design, selectors, middleware, SSR, and testing. Use when creating or refactoring Zustand stores, deciding whether state belongs in Zustand vs component state vs a server-state library, optimizing selector re-renders, adding persist/devtools/immer middleware, or handling Zustand with SSR/React Server Components."
metadata:
  maintainer: Mindrally
  source: https://github.com/Mindrally/skills
---

# Zustand State Management

This skill covers designing and using Zustand stores in React and TypeScript applications, including state ownership decisions, store slicing, selector performance, middleware, SSR, and testing.

## State Ownership

- Keep ephemeral UI state in the nearest component with `useState` or `useReducer` — don't reach for Zustand by default.
- Use URL state for shareable filters, pagination, tabs, and search params.
- Use Zustand only for client state that is genuinely shared across unrelated components (auth session view state, command palette, cart draft, editor state, etc.).
- Use TanStack Query, SWR, RTK Query, or the project's existing data layer for server state — don't duplicate fetched server data into a Zustand store unless there's a documented offline or draft-editing requirement.
- Implement functional, declarative patterns; avoid classes. Use descriptive variable names with auxiliary verbs like `isLoading`, `hasError`.

## Store Design

- Model each store as state plus named actions; avoid exposing anonymous setters for component code to misuse.
- Keep stores small and domain-focused rather than one global store for the entire application.
- Split large stores into typed slices, then apply middleware only at the composed store boundary.
- Keep derived values as selectors or small pure helpers unless they must be cached in state.
- Store serializable data by default; keep DOM nodes, promises, sockets, and timers outside store state.

```typescript
import { create } from 'zustand'

interface SidebarState {
  isOpen: boolean
  activePanelId: string | null
}

interface SidebarActions {
  openPanel: (panelId: string) => void
  close: () => void
  toggle: () => void
}

type SidebarStore = SidebarState & SidebarActions

export const useSidebarStore = create<SidebarStore>()((set) => ({
  isOpen: false,
  activePanelId: null,
  openPanel: (panelId) => set({ isOpen: true, activePanelId: panelId }),
  close: () => set({ isOpen: false, activePanelId: null }),
  toggle: () => set((state) => ({ isOpen: !state.isOpen })),
}))
```

## Component Usage & Performance

- Subscribe to the smallest possible slice: `useStore((state) => state.value)`. Avoid selecting the entire store.
- Do not call a store hook without a selector in components unless the component truly needs every field.
- Use `useShallow` (from `zustand/react/shallow`) when a selector returns an object or tuple of multiple values, to avoid re-renders from a new object reference each call.
- Keep selectors pure and cheap; move expensive derivations into memoized helpers.

```tsx
import { useShallow } from 'zustand/react/shallow'
import { useSidebarStore } from '@/stores/sidebar-store'

export function SidebarToggle() {
  const { isOpen, toggle } = useSidebarStore(
    useShallow((state) => ({
      isOpen: state.isOpen,
      toggle: state.toggle,
    })),
  )

  return (
    <button type="button" aria-expanded={isOpen} onClick={toggle}>
      Toggle sidebar
    </button>
  )
}
```

## TypeScript

- Define explicit state and action interfaces for shared stores; combine them (`type Store = State & Actions`) rather than one flat interface for non-trivial stores.
- Avoid `any`; use `unknown` plus narrowing for external data.
- Type action payloads and return values, including async actions.
- Prefer discriminated unions for complex local status instead of several loosely related booleans.
- Export store state types when tests, utilities, or vanilla store factories need them.

## Middleware

### Updates
- Use functional `set((state) => nextState)` when the next value depends on current state.
- Treat nested state immutably; install and use the `immer` middleware only when it materially simplifies nested updates — don't mutate nested objects directly without it.

### Persistence
```typescript
import { persist } from 'zustand/middleware'

const useStore = create(
  persist(
    (set) => ({
      // state and actions
    }),
    { name: 'store-key' }
  )
)
```
- Use `persist` only for state that must survive reloads.
- Use `partialize`, `version`, and `migrate` when persisting anything beyond trivial preferences.
- Never persist secrets, access tokens, refresh tokens, raw PII, or other long-lived authorization state to browser storage.

### DevTools
```typescript
import { devtools } from 'zustand/middleware'

const useStore = create(
  devtools((set) => ({
    // state and actions
  }))
)
```
- Use `devtools` in development for complex flows and give important actions clear names so they're identifiable in the trace.

### Non-React Subscriptions
- Use `subscribeWithSelector` for non-React subscriptions that need fine-grained updates outside of component rendering.

## Async Actions & Error Handling

- Async store actions should coordinate client-only workflows, optimistic drafts, or local device APIs — keep HTTP fetching in the project's server-state layer unless the state is explicitly client-owned.
- Represent async client workflows with explicit statuses such as `idle`, `pending`, `success`, and `error` rather than ad hoc booleans.
- Handle errors at function start using early returns and guard clauses; use try-catch in async actions and provide meaningful error messages.
- Reset error state deliberately when retrying or closing a workflow.

## SSR and React Server Components

- Do not read or mutate browser-only stores from React Server Components.
- In SSR frameworks (Next.js App Router, etc.), create per-request vanilla stores when state must be initialized on the server, rather than a shared module-level store.
- Guard persisted stores against hydration mismatches before rendering storage-backed values.
- Keep store modules free of direct `window`, `document`, and storage access outside middleware configuration.

## Testing

- Test stores independently of components — test store actions directly without rendering React when possible.
- Reset stores between tests with their initial state.
- Assert selectors and actions separately from component behavior; mock Zustand stores in component tests when isolating UI logic.
- Mock server-state libraries instead of routing fetched data through Zustand for tests.
- Test middleware behavior (persistence, devtools) separately from core store logic.

## Anti-Patterns

- Do not create one global store for the entire application.
- Do not put form input state in Zustand unless multiple distant components edit the same draft.
- Do not mutate nested objects directly without Immer middleware.
- Do not use Zustand as an event bus; prefer explicit callbacks, services, or a scoped store.
- Do not introduce Redux-style reducers, action constants, or dispatch wrappers unless the project already uses that pattern.

© Mindrally · Apache-2.0 · Mindrally/skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →
state-management agent-skills Скилл с готовыми паттернами TanStack Query v5 и Zustand v5: запросы, кеш, мутации, оптимистичные обновления и клиентские сторы. CX Codex +1 783установок frontend-state-management aj-geddes Скилл для работы с состоянием фронтенда: подсказывает, как организовать Redux, MobX, Zustand или Context API в приложении. CX Codex +1 480установок zustand pproenca Скилл с 43 правилами для Zustand в React: архитектура сторов, селекторы, лишние ре-рендеры. Пригодится, когда пишете или рефакторите стор. CX Codex +1 446установок React State Management taste f Сводка правил по управлению состоянием в React: когда использовать useState, Zustand, Context и TanStack Query. Помогает избежать типичных ошибок вроде лишних глобальных сторов. GP ChatGPT ★ 174 597звёзд репо zustand-patterns OrchestKit Справочник по управлению состоянием на Zustand 5.x: слайсы, middleware, Immer, useShallow, персистентность и devtools. Пригодится, когда хочется уйти от Redux без лишнего кода. CX Codex +1 1 400установок zustand-5 prowler-cloud Скилл с паттернами управления состоянием в Zustand 5: базовые хранилища, селекторы, persist-middleware и разделение логики на слайсы. Помогает писать чистый реактивный код без лишних ре-рендеров. CX Codex +1 911установок

Из того же набора168

nlp-natural-language-processing Набор инструкций для NLP-разработки: токенизация, классификация, spaCy, NLTK и поиск по эмбеддингам. Помогает агенту писать чистый Python-код по стандартам PEP 8. CX Codex +1 980установок ui-design Задаёт агенту правила вёрстки и интерфейсов: доступность, адаптивность, производительность. Пригодится, когда агент пишет фронтенд и вы хотите предсказуемый результат. CX Codex +1 981установок internationalization-i18n Скилл задаёт агенту правила интернационализации: переводы, форматирование дат и чисел, RTL-раскладка. Пригодится, когда приложение выходит на новые языки. CX Codex +1 978установок java Скилл задаёт агенту правила Java-разработки: слоистая структура, Spring Boot 3.x, тесты на JUnit и Mockito. Пригодится, когда проект на Java растёт и код надо держать в одном стиле. CX Codex +1 966установок typescript Задаёт правила типизации и структуры кода на TypeScript для ассистента. Помогает писать функции короче 20 строк, заменять enums на maps и избегать any. CX Codex +1 955установок python-uv Заставляет агента ставить и синхронизировать Python-пакеты только через uv, без pip и poetry. Пригодится, если в проекте уже есть uv или вы устали от разъезжающихся окружений. CX Codex +1 956установок pixi-js Скилл для ИИ-агента: подсказывает, как писать игры на Pixi.js с TypeScript и оптимизировать их под веб и мобильные устройства. CX Codex +1 948установок deep-learning Задаёт агенту правила проектирования и обучения нейросетей: архитектура, оптимизаторы, mixed precision, память. Пригодится, когда пишете или правите код модели. CX Codex +1 946установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой