React Zustand
Cursor-Regel für React mit Zustand: schlanker, konsistenter Store-Code statt Redux-Boilerplate.
Cursor-Regel für React mit Zustand: schlanker, konsistenter Store-Code statt Redux-Boilerplate.
Original-Beschreibung der Autoren: React and TypeScript state management guidance for Zustand stores, selectors, middleware, persistence, and testing.
Die Regel
---
description: "React and TypeScript state management guidance for Zustand stores, selectors, middleware, persistence, and testing."
globs: **/*.ts, **/*.tsx
alwaysApply: false
---
You are an expert in React, TypeScript, and Zustand state management.
# React + Zustand Guidelines
## State Ownership
- Keep ephemeral UI state in the nearest component with `useState` or `useReducer`.
- Use URL state for shareable filters, pagination, tabs, and search params.
- Use Zustand only for client state that is genuinely shared across unrelated components.
- Use TanStack Query, SWR, RTK Query, or the existing project data layer for server state.
- Never duplicate fetched server data into a Zustand store unless there is a documented offline or draft-editing requirement.
## 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: auth session view state, command palette state, cart draft state, editor state, etc.
- 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.
```ts
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
- Subscribe to the smallest possible slice:
useStore((state) => state.value). - Do not call a store hook without a selector in components unless the component truly needs every field.
- Select actions separately or through a shallow selector when grouping them.
- Use
useShallowfor object or tuple selectors that return multiple values. - Keep selectors pure and cheap; move expensive derivations into memoized helpers if needed.
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.
- Avoid
any; useunknownplus 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.
Updates and Middleware
- Use functional
set((state) => nextState)when the next value depends on current state. - Treat nested state immutably; install and use
immermiddleware only when it materially simplifies nested updates. - Use
persistonly for state that must survive reloads. - Use
partialize,version, andmigratewhen persisting anything beyond trivial preferences. - Never persist secrets, access tokens, refresh tokens, raw PII, or long-lived authorization state to browser storage.
- Use
devtoolsin development for complex flows and give important actions clear names. - Use
subscribeWithSelectorfor non-React subscriptions that need fine-grained updates.
Async Actions
- Async store actions may 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, anderror. - 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, create per-request vanilla stores when state must be initialized on the server.
- 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 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 server-state libraries instead of routing fetched data through Zustand for tests.
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.
## So nutzt du sie
Die Regel kopieren (Button oben) oder als Datei herunterladen und im Projekt unter `.cursor/rules/` ablegen — Cursor lädt sie beim nächsten Start automatisch. Ältere Cursor-Versionen lesen alternativ eine einzelne `.cursorrules`-Datei im Projektstamm; dort einfach den Regel-Text ohne den Kopfblock zwischen den `---`-Zeilen einfügen.
Der Regel-Text ist englisch — Cursor versteht ihn unabhängig von der Sprache, in der Sie mit dem Editor chatten.
## Im Detail
Diese Cursor-Regel bündelt Konventionen für React-Projekte, die Zustand als State-Management-Lösung einsetzen. Statt Redux-typischer Boilerplate setzt Zustand auf schlanke Stores — die Regel sorgt dafür, dass Cursor beim Generieren und Ändern von Code genau diesen schlanken Stil einhält: klare Store-Struktur, sinnvolle Selektoren, keine unnötige Verschachtelung. Praktisch für alle, die in bestehenden Zustand-Projekten arbeiten oder neu darauf umsteigen und wollen, dass generierter Code sofort zum Rest der Codebase passt, statt in Redux-Denkmuster zurückzufallen. Wie bei allen Cursor-Regeln gilt: Sie ersetzt keine Doku, sondern lenkt nur, wie die KI beim Schreiben von Code entscheidet.
## Praxis-Tipp
In .cursor/rules/ speichern, dann z. B. prompten: „Lege einen Zustand-Store für den Warenkorb an“ — Cursor folgt automatisch den hinterlegten Store-Konventionen statt eigener Annahmen.
## Siehe auch
- [Anti Overengineering](/ki-verzeichnis/ide-tools/anti-overengineering/)
## Lizenz & Quelle
- **Lizenz:** CC0 1.0
- **Quelle:** [PatrickJS/awesome-cursorrules (GitHub)](https://github.com/PatrickJS/awesome-cursorrules)
Inhalt ansehen (react-zustand.mdc)
Lade …
Erfahrungen & Kommentare.
Funktioniert der Regel bei Ihnen? Tipps, Stolperfallen, Varianten — teilen Sie es mit der Community.
Lade Kommentare …
Passt dazu.
AI Agent Specialist
Cursor-Regel, die den KI-Editor auf diszipliniertes, spezialisiertes Agenten-Verhalten trimmt.
Alpha Skills Quant Factor Research
Cursor-Regel für quantitative Faktor-Recherche im Trading/Finance-Bereich — leitet die KI zu methodisch sauberer Analyse an.
Android Jetpack Compose
Cursor-Regel für Android-Entwicklung mit Jetpack Compose — sorgt für idiomatischen, deklarativen Kotlin-UI-Code.
