lenec ru

← все посты

Pydantic v2: что нового, миграция с v1 и реальные бенчмарки

15K

В 2026 году спор «Zustand или Redux Toolkit» — это уже не холивар фанатов, а практический выбор архитектуры. Оба инструмента зрелые, оба поддерживают TypeScript из коробки. Но подходят они для разных ситуаций. Разберём с кодом, цифрами и чеклистом в конце.

Архитектурные отличия: store, slices, middleware

Redux Toolkit (RTK) строится вокруг единого store с разделением на slices. Каждый slice — reducer + actions + начальное состояние:

import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit';

interface CounterState { value: number }

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 } as CounterState,
  reducers: {
    increment(state) { state.value += 1 },
    incrementBy(state, action: PayloadAction<number>) {
      state.value += action.payload;
    },
  },
});

export const store = configureStore({
  reducer: { counter: counterSlice.reducer },
});

Zustand — минималистичный store без boilerplate. Нет slices, нет dispatch, нет action creators:

import { create } from 'zustand';

interface CounterStore {
  value: number;
  increment: () => void;
  incrementBy: (n: number) => void;
}

export const useCounterStore = create<CounterStore>((set) => ({
  value: 0,
  increment: () => set((s) => ({ value: s.value + 1 })),
  incrementBy: (n) => set((s) => ({ value: s.value + n })),
}));

Ключевое отличие: в RTK логика обновления отделена от состояния (reducers), в Zustand — методы живут рядом с данными. RTK навязывает структуру, Zustand даёт свободу.

Размер бандла и tree-shaking

  • Zustand — ~1.1 KB (minified + gzip). Без зависимостей. Полностью tree-shakeable.
  • Redux Toolkit — ~12-14 KB (redux + immer + RTK). Immer один весит ~6 KB.

Для SPA разница некритична. Но для виджетов, Chrome-расширений или Astro islands с бюджетом 50 KB — Zustand выигрывает однозначно.

DevTools и отладка

Redux DevTools — золотой стандарт: time-travel, diff состояний, запись сессий. RTK подключает их автоматически.

Zustand тоже поддерживает Redux DevTools через middleware:

import { devtools } from 'zustand/middleware';

const useStore = create<MyState>()(
  devtools(
    (set) => ({
      count: 0,
      inc: () => set((s) => ({ count: s.count + 1 }), false, 'inc'),
    }),
    { name: 'MyStore' }
  )
);

Работает, но без автоматических имён экшенов — надо передавать третьим аргументом в set. Time-travel менее надёжен при сложных обновлениях. Для серьёзной отладки RTK удобнее.

Паттерны: async actions, selectors, persist

Асинхронные действия. В RTK — createAsyncThunk или RTK Query. В Zustand — просто async-функция:

// Zustand
const useUsersStore = create<UsersStore>((set) => ({
  users: [],
  loading: false,
  fetchUsers: async () => {
    set({ loading: true });
    const res = await fetch('/api/users');
    set({ users: await res.json(), loading: false });
  },
}));

RTK Query даёт кеширование, инвалидацию, polling из коробки. У Zustand для этого нужен TanStack Query или SWR рядом.

Selectors. Zustand — selector прямо в хуке, компонент ре-рендерится только при изменении выбранного поля:

const users = useUsersStore((s) => s.users);

Persist. Zustand — через middleware persist:

import { persist } from 'zustand/middleware';

const useSettingsStore = create<SettingsStore>()(
  persist(
    (set) => ({
      theme: 'dark',
      setTheme: (t: string) => set({ theme: t }),
    }),
    { name: 'settings-storage' }
  )
);

В RTK — через redux-persist с дополнительной конфигурацией (persistReducer, persistGate, blacklist/whitelist).

Чеклист выбора

Выбирай Zustand, если:

  • Проект небольшой или средний (до 10-15 сторов)
  • Команда маленькая (1-5 человек), нет нужды в строгих конвенциях
  • Критичен размер бандла (виджеты, микрофронтенды)
  • Состояние простое: UI-флаги, формы, кеш данных
  • Уже используешь TanStack Query для серверного состояния

Выбирай Redux Toolkit, если:

  • Большая команда (5+ человек) — RTK навязывает единый стиль
  • Сложная бизнес-логика с цепочками side-effects
  • Нужен RTK Query для data fetching с кешированием
  • Критична отладка: time-travel, запись сессий
  • Проект долгоживущий (3+ лет) — экосистема Redux стабильнее
  • Уже есть Redux — миграция на RTK проще, чем переезд на Zustand

Гибридный подход тоже работает: RTK Query для серверного кеша + Zustand для UI-состояния. Они не конфликтуют в одном приложении.

Не выбирай инструмент по хайпу. Zustand модный и минималистичный, но на проекте с 50 разработчиками его свобода превращается в хаос. Redux «тяжёлый», но его предсказуемость — то, за что платят в enterprise. Оцени команду, масштаб и горизонт — ответ придёт сам.

Комментарии 0

  • Будьте первым, кто оставит комментарий.

Войдите, чтобы оставить комментарий.