lenec ru

← все посты

Zustand vs Redux Toolkit vs Jotai в 2026

16K

За последние пять лет я работала с тремя разными подходами к управлению состоянием в React: Redux Toolkit, Zustand и Jotai. На разных проектах — разные, и каждый раз выбор был осмысленным, а не «просто потому что». В 2026 году картина устаканилась: каждая библиотека закрепилась за своей нишей, и пайплайн выбора стал понятнее.

В двух предложениях о каждой

Redux Toolkit — большой централизованный стор с строгими правилами. Лучшая поддержка инструментами (DevTools, time-travel, middleware), отличная документация, отработанные паттерны для команды.

Zustand — легковесный стор без boilerplate. Минимум API, максимум контроля, прекрасно интегрируется с TypeScript. Любой junior разбирается за полчаса.

Jotai — атомарное состояние. Каждое значение — отдельный атом, компоненты подписываются точечно. Изысканная модель для UI с большим количеством мелких независимых стейтов.

Когда я беру Redux Toolkit

Большие проекты, где над кодом работает много команд. RTK даёт каркас, который не разваливается, когда у тебя в проекте сорок разработчиков. Все знают, что такое slice, что такое reducer, как работает createAsyncThunk. На ревью не нужно пересказывать архитектуру — она в библиотеке.

RTK Query особенно хорош, когда ты хочешь типизированный API-клиент с автоматическим кешированием. По сравнению с обычным createApi в каноническом Redux он сильно ускоряет работу: эндпоинты описываются один раз, хуки генерируются автоматически.

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';

export const api = createApi({
  baseQuery: fetchBaseQuery({ baseUrl: '/api' }),
  tagTypes: ['Post'],
  endpoints: (b) => ({
    getPosts: b.query<Post[], void>({
      query: () => '/posts',
      providesTags: ['Post'],
    }),
    addPost: b.mutation<Post, Partial<Post>>({
      query: (body) => ({ url: '/posts', method: 'POST', body }),
      invalidatesTags: ['Post'],
    }),
  }),
});

export const { useGetPostsQuery, useAddPostMutation } = api;

В компонентах хуки выглядят как обычные React-хуки, но за ними — кеш, ревалидации и работа с гонками.

Минусы Redux Toolkit

Boilerplate. Даже с RTK на простой счётчик уходит десяток строк. На лендинг с минимальной интерактивностью ставить целый Redux — оверкилл.

Серверные компоненты в Next.js. Redux нативно живёт на клиенте, и в RSC его не используешь. Можно держать кеш данных на сервере отдельно (через cache и revalidateTag), а Redux оставить только для клиентского state. Эта граница в архитектуре требует внимания.

Когда я беру Zustand

Средний и маленький проект, в котором нужен общий state, но не хочется тащить тяжёлую инфраструктуру. Zustand — мой дефолт уже два года.

import { create } from 'zustand';

type CartState = {
  items: { id: string; qty: number }[];
  add: (id: string) => void;
  clear: () => void;
};

export const useCart = create<CartState>((set) => ({
  items: [],
  add: (id) =>
    set((s) => {
      const existing = s.items.find((i) => i.id === id);
      if (existing) {
        return { items: s.items.map((i) => (i.id === id ? { ...i, qty: i.qty + 1 } : i)) };
      }
      return { items: [...s.items, { id, qty: 1 }] };
    }),
  clear: () => set({ items: [] }),
}));

В компоненте:

const items = useCart((s) => s.items);
const add = useCart((s) => s.add);

Это всё. Подписка точечная (по селектору), DevTools работают через middleware, persist в localStorage — одна строчка.

Zustand хорошо подходит для UI-state: открыта ли модалка, какая активная вкладка, какие фильтры применены. Я в одном проекте держу штук десять отдельных сторов: для аутентификации, для UI-настроек, для корзины, для черновиков. Это не перегружает архитектуру и легко читается.

Когда я беру Jotai

Когда состояние очень атомарное и не складывается в централизованный слайс. Самый частый кейс — сложные формы с большим количеством зависимых полей.

import { atom, useAtom } from 'jotai';

const nameAtom = atom('');
const emailAtom = atom('');
const isValidAtom = atom((get) => {
  const name = get(nameAtom);
  const email = get(emailAtom);
  return name.length > 1 && email.includes('@');
});

function Form() {
  const [name, setName] = useAtom(nameAtom);
  const [email, setEmail] = useAtom(emailAtom);
  const [valid] = useAtom(isValidAtom);
  // ...
}

Производное значение isValidAtom само пересчитается, когда изменится один из источников. И каждый компонент подписан только на свои атомы — никаких лишних перерисовок.

Jotai сильна в дизайн-системах с большим количеством взаимосвязанных контролов. На дашбордах со сложными фильтрами, на конструкторах форм она экономит много кода. На обычной CRUD-административке выглядит избыточно.

Сравнение по 7 критериям

В сухой таблице оно бы выглядело так, но я обещала не делать таблиц — пройдусь списком.

  • Boilerplate. Меньше всех — Zustand. Чуть больше — Jotai (но без структуры). Больше всех — RTK.
  • DevTools. Лучше всех — RTK. Хорошо — Zustand (через middleware). Слабее — Jotai (есть, но кустарные).
  • TypeScript. Все три отлично типизированы. Zustand чуть проще пишется, RTK даёт строгие сигнатуры из коробки, Jotai требует немного танцев со WritableAtom<V, A, R>.
  • SSR / Next App Router. Все три работают, но требуют аккуратности с гидрацией. Zustand часто использую с инициализацией через провайдер. RTK — официальный гайд по SSR. Jotai — провайдер с store.
  • Кеш данных с сервера. RTK Query — встроен. Для Zustand и Jotai я беру TanStack Query.
  • Кривая обучения. Меньше всего — Zustand, день. Jotai — два-три дня, чтобы привыкнуть к атомам. RTK — неделя на освоение всех концептов.
  • Подходит junior-команде. Zustand. RTK слишком формальный, Jotai требует ментальной перестройки.

Что я не использую

Recoil. На бумаге похож на Jotai, но в 2026 году развивается медленнее, и почти всё, что есть в Recoil, есть в Jotai в более чистом виде.

MobX. Прекрасная библиотека, но сильно вышла из моды, и команда сейчас редко её знает. Я бы не закладывала её в новый проект, если только не работаю в окружении, где это уже стандарт.

Redux без Toolkit. Бесполезный самобичевание. RTK — это «правильный Redux», и любой свежий проект на классическом Redux — это технический долг с первого дня.

Гибридные подходы

На большом проекте можно держать всё одновременно. У меня сейчас:

  • RTK Query — для всех серверных данных (CRUD-эндпоинты).
  • Zustand — для UI-настроек и корзины.
  • Jotai — для одного конструктора форм с двадцатью полями.

Звучит как «зоопарк», но на практике работает. Каждая библиотека делает свою задачу, и команда быстро привыкает: «серверные данные — RTK, UI — Zustand, форма — Jotai». Главное не плодить дубликаты: одно и то же состояние не должно жить в двух местах.

Что копать дальше

Если ты впервые выбираешь, бери Zustand на первый проект. Он самый простой и не накладывает ограничений на архитектуру. Через год-другой, когда команда вырастет, перейти на RTK будет несложно — слайсы можно постепенно мигрировать. Jotai разумно начать использовать, когда ты увидишь конкретный кейс, который в Zustand плохо ложится.

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

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

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