MobX и Ant Design

Для работы с MobX в проектах на React с использованием Ant Design необходимо сначала установить зависимости:

npm install mobx mobx-react-lite antd

MobX используется для управления состоянием приложения через observable объекты и actions, а Ant Design предоставляет компоненты пользовательского интерфейса. Интеграция заключается в том, чтобы состояния, управляемые MobX, напрямую отражались в компонентах Ant Design через реактивное связывание.


Создание наблюдаемого состояния

Для примера создадим стор для управления списком задач:

import { makeAutoObservable } from "mobx";

class TodoStore {
  todos = [];
  filter = "";

  constructor() {
    makeAutoObservable(this);
  }

  addTodo(title) {
    this.todos.push({ title, completed: false });
  }

  toggleTodo(index) {
    this.todos[index].completed = !this.todos[index].completed;
  }

  setFilter(value) {
    this.filter = value;
  }

  get filteredTodos() {
    if (!this.filter) return this.todos;
    return this.todos.filter(todo => todo.title.includes(this.filter));
  }
}

export const todoStore = new TodoStore();

Ключевые моменты:

  • makeAutoObservable автоматически делает все свойства observable и методы — actions.
  • get filteredTodos — это вычисляемое свойство (computed), автоматически обновляющее компоненты при изменении зависимостей.

Подключение MobX к компонентам Ant Design

Используется observer из mobx-react-lite, чтобы компонент реагировал на изменения состояния:

import { observer } from "mobx-react-lite";
import { Input, List, Button, Checkbox } from "antd";
import { todoStore } from "./TodoStore";

const TodoApp = observer(() => {
  return (
    <div style={{ maxWidth: 400, margin: "0 auto" }}>
      <Input.Search
        placeholder="Фильтр задач"
        value={todoStore.filter}
        onCha nge={(e) => todoStore.setFilter(e.target.value)}
        style={{ marginBottom: 20 }}
      />
      <List
        bordered
        dataSource={todoStore.filteredTodos}
        renderItem={(item, index) => (
          <List.Item
            actions={[
              <Button onCl ick={() => todoStore.toggleTodo(index)}>
                {item.completed ? "Отметить как невыполнено" : "Выполнено"}
              </Button>,
            ]}
          >
            <Checkbox checked={item.completed}>{item.title}</Checkbox>
          </List.Item>
        )}
      />
    </div>
  );
});

export default TodoApp;

Особенности интеграции:

  • Любые изменения в todoStore автоматически перерисовывают компоненты Ant Design.
  • Input.Search напрямую связывается с наблюдаемым свойством filter.
  • List использует dataSource из MobX, обеспечивая динамическое обновление элементов списка.

Использование Form Ant Design с MobX

Формы Ant Design могут работать с MobX через синхронизацию значений:

import { Form, Input, Button } from "antd";
import { observer } from "mobx-react-lite";
import { todoStore } from "./TodoStore";

const AddTodoForm = observer(() => {
  const [form] = Form.useForm();

  const onFin ish = (values) => {
    todoStore.addTodo(values.title);
    form.resetFields();
  };

  return (
    <Form form={form} layout="inline" onFin ish={onFinish}>
      <Form.Item
        name="title"
        rules={[{ required: true, message: "Введите название задачи" }]}
      >
        <Input placeholder="Новая задача" />
      </Form.Item>
      <Form.Item>
        <Button type="primary" htmlType="submit">
          Добавить
        </Button>
      </Form.Item>
    </Form>
  );
});

export default AddTodoForm;

Ключевые моменты:

  • Form Ant Design используется как контролируемый компонент.
  • После успешного добавления задачи вызывается метод MobX addTodo, обновляющий состояние и перерисовывающий список.

Реактивная фильтрация и сортировка с MobX

MobX упрощает реактивную фильтрацию и сортировку компонентов Ant Design. Например, добавим возможность сортировать задачи по статусу:

get sortedTodos() {
  return this.filteredTodos.slice().sort((a, b) => a.completed - b.completed);
}

В компоненте List можно заменить dataSource={todoStore.filteredTodos} на dataSource={todoStore.sortedTodos}. Все изменения фильтра или статуса задач автоматически отражаются на UI без ручного обновления.


Работа с Modals и Notifications

Ant Design предоставляет Modal и notification, а MobX может управлять их состоянием:

import { Modal, Button, notification } from "antd";
import { makeAutoObservable } from "mobx";

class UiStore {
  isModalVisible = false;

  constructor() {
    makeAutoObservable(this);
  }

  showModal() {
    this.isModalVisible = true;
  }

  hideModal() {
    this.isModalVisible = false;
  }

  notifySuccess(message) {
    notification.success({ message });
  }
}

export const uiStore = new UiStore();

Использование в компоненте:

import { observer } from "mobx-react-lite";
import { uiStore } from "./UiStore";
import { Modal, Button } from "antd";

const ModalExample = observer(() => (
  <>
    <Button onCl ick={() => uiStore.showModal()}>Показать модальное окно</Button>
    <Modal
      visible={uiStore.isModalVisible}
      onOk={() => { uiStore.hideModal(); uiStore.notifySuccess("Ок подтвержден"); }}
      onCan cel={() => uiStore.hideModal()}
    >
      Контент модального окна
    </Modal>
  </>
));

export default ModalExample;

Вывод: состояние модального окна полностью контролируется MobX, а компоненты Ant Design автоматически реагируют на его изменения.


Рекомендации по организации проекта

  • Хранить store в отдельной папке stores.
  • Разделять UI-компоненты и бизнес-логику. UI использует только наблюдаемые свойства.
  • Использовать computed properties для фильтров и сортировки, чтобы минимизировать перерисовки.
  • Использовать observer только для компонентов, которые реально зависят от состояния.

Эта структура обеспечивает максимально чистую и реактивную интеграцию MobX и Ant Design, позволяя создавать сложные интерфейсы с минимальным количеством ручного состояния.