Перейти к содержимому

59. MobX: Введение

MobX: Введение в реактивное программирование 🧲

Заголовок раздела «MobX: Введение в реактивное программирование 🧲»

MobX — это библиотека для управления состоянием, основанная на принципах реактивного программирования. Вместо того чтобы описывать как обновлять UI, ты просто описываешь что является состоянием — и MobX сам следит за всеми зависимостями и обновляет только то, что нужно. ✨


1. Что такое реактивное программирование? 🤔

Заголовок раздела «1. Что такое реактивное программирование? 🤔»

Представь электронную таблицу Excel. Ты вводишь число в ячейку A1, и все формулы, которые зависят от A1, автоматически пересчитываются. Тебе не нужно вручную говорить Excel “пересчитай B1 и C3” — он делает это сам.

MobX работает точно так же! Ты объявляешь данные как наблюдаемые (observable), а потом любой код, который их читает, автоматически становится реактивным — он будет выполняться заново при изменении данных.

import { makeAutoObservable } from 'mobx';
class CounterStore {
count = 0; // 👈 это наблюдаемое значение
constructor() {
makeAutoObservable(this);
}
increment() {
this.count++; // 👈 это действие, меняющее состояние
}
}
// Любой компонент, который читает store.count,
// автоматически перерендерится при его изменении!

MobX строится на трёх фундаментальных концепциях:

Это твоё состояние — объекты, массивы, примитивы, которые MobX отслеживает.

import { observable, makeObservable } from 'mobx';
class Store {
@observable count = 0;
@observable name = 'Яша';
@observable items: string[] = [];
}

Единственный правильный способ изменять observable-данные. Это как “команды” в военном лагере — только через официальный приказ.

import { action, makeObservable } from 'mobx';
class Store {
@action increment() {
this.count++;
}
@action setName(name: string) {
this.name = name;
}
}

Код, который автоматически запускается при изменении observable-данных. Реакции — это “слушатели” изменений.

import { autorun, reaction } from 'mobx';
// autorun — запускается сразу и при каждом изменении
autorun(() => {
console.log('Count изменился:', store.count);
});
// reaction — запускается только когда возвращаемое значение изменяется
reaction(
() => store.count,
(count) => console.log('Новое значение:', count)
);

Самое крутое в MobX — это автоматическое отслеживание зависимостей. Тебе не нужно писать connect(), mapStateToProps() или список зависимостей как в useEffect. MobX сам видит, какие observable читаются во время выполнения реакции.

const store = observable({
firstName: 'Иван',
lastName: 'Петров',
age: 25,
});
// MobX автоматически понимает, что эта реакция
// зависит от firstName И lastName, но НЕ от age
autorun(() => {
console.log(`${store.firstName} ${store.lastName}`);
// age здесь не читается — изменение age не вызовет эту реакцию!
});

Выбор стейт-менеджера — это как выбор инструмента. Молоток — не лучше отвёртки, просто для разных задач.

ХарактеристикаMobXRedux ToolkitZustand
ФилософияМутабельность (ООП)Иммутабельность (FP)Мутабельность (лёгкость)
Бойлерплейт🟢 Минимум🟡 Средний🟢 Минимум
Размер бандла~60 кб~40 кб~3 кб
TypeScript🟢 Отличный🟡 Хороший🟢 Отличный
DevTools🟡 Есть🟢 Отличные🟡 Базовые
Кривая обучения🟡 Средняя🔴 Высокая🟢 Низкая
OOP-стиль🟢 Идеальный🔴 Нет🟡 Частично
Реактивность🟢 Автоматическая🔴 Ручная🟡 Полуавтоматическая
Подходит дляСложный стейт, ООППредсказуемость, дебаггингПростые приложения

Redux требует, чтобы ты никогда не мутировал состояние. Каждое изменение создаёт новый объект:

// Redux — иммутабельный подход
const newState = {
...state,
count: state.count + 1, // создаём новый объект!
};

MobX позволяет напрямую изменять состояние, как в обычном JavaScript:

// MobX — мутабельный подход
store.count++; // просто изменяем! MobX отследит это сам
store.items.push('новый элемент');
store.user.name = 'Петя';

Это делает MobX очень интуитивным, особенно если ты знаком с ООП.


MobX — хороший выбор когда:

  • Ты пишешь приложение в ООП-стиле с классами
  • У тебя сложная доменная модель с множеством взаимосвязей
  • Команда привыкла к Angular/Vue (похожая реактивность)
  • Хочешь минимум бойлерплейта
  • Данные часто меняются (игры, real-time приложения)

Лучше выбрать другой инструмент когда:

  • Нужны отличные DevTools для time-travel debugging → Redux
  • Маленькое приложение с простым стейтом → Zustand или useState
  • Команда работает в функциональном стиле → Redux Toolkit
  • Нужна максимальная предсказуемость → Redux

Окно терминала
npm install mobx mobx-react-lite
store.ts
import { makeAutoObservable } from 'mobx';
class AppStore {
count = 0;
constructor() {
makeAutoObservable(this);
}
increment() {
this.count++;
}
}
export const store = new AppStore();
App.tsx
import { observer } from 'mobx-react-lite';
import { store } from './store';
// observer() — оборачивает компонент, делая его реактивным
const App = observer(() => (
<button onClick={() => store.increment()}>
Клики: {store.count}
</button>
));

MobX — это мощный инструмент реактивного программирования, который делает управление состоянием простым и интуитивным. Главные идеи:

  • 🟣 Observable — наблюдаемые данные (твой стейт)
  • 🔵 Action — единственный способ менять стейт
  • 🟢 Reaction/Computed — автоматические ответы на изменения
  • Автоматическое отслеживание зависимостей — MobX сам знает, кто от чего зависит
  • 🔄 Мутабельность — меняй состояние как обычный JS объект

В следующих уроках мы разберём каждую концепцию подробно! 💪