Skip to content

Instantly share code, notes, and snippets.

@tomasevich
Created April 23, 2026 06:56
Show Gist options
  • Select an option

  • Save tomasevich/d5be0aa46edf3eded6e696006303c363 to your computer and use it in GitHub Desktop.

Select an option

Save tomasevich/d5be0aa46edf3eded6e696006303c363 to your computer and use it in GitHub Desktop.
Сравнение Zustand vs Redux vs Context vs MobX

Сравнение Zustand vs Redux vs Context vs MobX

Менеджеры состояний и контекста

Выбор между этими инструментами зависит от масштаба проекта, опыта команды и требований к производительности.

Краткое сравнение

Характеристика React Context Zustand Redux (Toolkit) MobX
Лучшее применение Темы, авторизация Малые и средние приложения Сложные корпоративные системы Часто меняющиеся данные
Количество кода Мало Очень мало Много (даже с RTK) Мало
Порог вхождения Низкий Низкий Высокий Средний
Перерендеры Часто (без оптимизации) Точечно (оптимизировано) Точечно (оптимизировано) Точечно (автоматически)
Поток данных Встроенный Provider Простые хуки Однонаправленный (Actions) Объекты (Observables)

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

  • Плюсы: Максимально простое API на основе хуков, не нужны провайдеры, отличная производительность "из коробки".
  • Минусы: В нем меньше строгой структуры, чем в Redux, что может быть важно для огромных проектов с десятками разработчиков.
  • Когда использовать: Почти в любом новом проекте, где нужен глобальный стейт без головной боли.

1.1. Создаем хранилище

import { create } from 'zustand'

const useCounter = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
}))

1.2. Используем в компоненте

function Counter() {
  const { count, increment, decrement } = useCounter()
  return (
    <div>
      <h1>{count}</h1>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
    </div>
  )
}

Проверенный временем инструмент, который навязывает строгую и предсказуемую архитектуру.

  • Плюсы: Мощные инструменты отладки (Redux DevTools), огромное сообщество, предсказуемость благодаря функциональному подходу.
  • Минусы: Избыточен для маленьких проектов, требует много кода даже при использовании современного Redux Toolkit.
  • Когда использовать: Большие корпоративные приложения со сложной логикой или в командах, где важны жесткие правила написания кода.

2.1. Создаем хранилище

import { createSlice } from '@reduxjs/toolkit'

const counterSlice = createSlice({
  name: 'counter',
  initialState: { value: 0 },
  reducers: {
    increment: (state) => { state.value += 1 }, // Можно "мутировать" благодаря Immer
  },
})

export const { increment } = counterSlice.actions
export default counterSlice.reducer

2.2. Используем в компоненте

import { useSelector, useDispatch } from 'react-redux'

function Counter() {
  const count = useSelector((state) => state.counter.value)
  const dispatch = useDispatch()
  return <button onClick={() => dispatch(increment())}>{count}</button>
}

Это часть самого React. Технически это не библиотека управления состоянием, а способ передачи данных через дерево компонентов без "прокидывания" пропсов.

  • Плюсы: Не увеличивает размер бандла, идеально для статических или редко меняющихся данных.
  • Минусы: Проблемы с производительностью при частых обновлениях, так как любое изменение стейта заставляет перерендериваться всех потребителей этого контекста.
  • Когда использовать: Для редко меняющихся данных: тема (темная/светлая), текущий язык интерфейса, данные авторизованного пользователя.

3.1. Создаем контекст

const CounterContext = createContext()

function CounterProvider({ children }) {
  const [count, setCount] = useState(0)
  return (
    <CounterContext.Provider value={{ count, setCount }}>
      {children}
    </CounterContext.Provider>
  )
}

3.2. Используем

function Counter() {
  const { count, setCount } = useContext(CounterContext)
  return <button onClick={() => setCount(count + 1)}>{count}</button>
}

MobX работает на основе "наблюдаемых" (observables) данных, на которые компоненты подписываются автоматически.

  • Плюсы: Минимум кода, работа в объектно-ориентированном стиле. Очень быстрая реакция на изменения.
  • Минусы: Сложнее отлаживать, так как обновления происходят "магически" под капотом; менее популярен в экосистеме React, чем Redux или Zustand.
  • Когда использовать: В приложениях с очень динамичными, взаимосвязанными данными или если вам привычнее мутировать объекты напрямую, а не работать с иммутабельностью.

4.1. Создаем хранилище

import { makeAutoObservable } from "mobx";

class CounterStore {
  count = 0;

  constructor() {
    // Делает всё в классе реактивным
    makeAutoObservable(this);
  }

  // Просто меняем значение напрямую
  increment() {
    this.count += 1;
  }

  decrement() {
    this.count -= 1;
  }
}

export const counterStore = new CounterStore();

4.2. Используем в компоненте

import React from "react";
import { observer } from "mobx-react-lite";
import { counterStore } from "./counterStore";

// observer следит за тем, какие данные из store используются в render
const Counter = observer(() => {
  return (
    <div>
      <h1>{counterStore.count}</h1>
      <button onClick={() => counterStore.increment()}>+</button>
      <button onClick={() => counterStore.decrement()}>-</button>
    </div>
  );
});

export default Counter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment