state-management
Клиентское состояние на Zustand — слайсы, селекторы, персист, экшены; граница «что НЕ поднимать в глобальный стор». Use при проектировании или правке клиентских сторов состояния во фронтенде.
SKILL.mdskills/state-management/SKILL.md
GitHubНавык: State management (Zustand)
Клиентское UI-состояние на Zustand. Серверные данные сюда не кладём — для них TanStack Query (скилл data-fetching).
Что держать в сторе
- Только клиентское UI-состояние: модалки, выбранные вкладки, черновики форм, тема, флаги.
- Не держи серверные данные (списки из API), производное состояние (вычисляй селектором) и то, что живёт локально в компоненте.
- Не храни переведённые строки — держи ключи/текущую локаль, а текст резолвь через слой перевода при рендере (скилл i18n).
Структура
- Стор на фичу (
src/features/<feature>/stores), а не один глобальный god-store. - Слайсы: разбивай большой стор на слайсы-функции
(set, get) => ({...})и объединяй. - Экшены — внутри стора (методы, вызывающие
set), а не разбросаны по компонентам.
Селекторы и перфоманс
- Подписывайся узко:
useStore(s => s.value), а не на весь стор — меньше перерендеров. - Для выборки нескольких полей —
useShallow(shallow-сравнение), чтобы не ловить лишние ререндеры.
Персист и middleware
persist— для сохранения (localStorage), сpartialize(что именно сохранять) иversion/migrate.devtools— для отладки;immer— для удобных иммутабельных обновлений вложенных структур.
Пример
export const useCartStore = create<CartState>()(
persist(
(set) => ({
items: [],
add: (item) => set((s) => ({ items: [...s.items, item] })),
clear: () => set({ items: [] }),
}),
{ name: "cart", partialize: (s) => ({ items: s.items }) },
),
);