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

Шаг 1. TaskStore (makeAutoObservable)

Начнём с сердца MobX-версии — класса TaskStore. Он заменяет useState из шага E1: хранит список задач и операции над ним.

  • Создай класс TaskStore с наблюдаемым полем tasks: Task[] (стартово — пустой массив);
  • сделай поля и методы реактивными одним вызовом makeAutoObservable(this) в конструкторе;
  • добавь actions: addTask(title), removeTask(id), toggleTask(id);
  • внутри actions меняй состояние напрямую (this.tasks.push(...), мутация полей) — MobX это отслеживает;
  • создай один экземпляр стора и временно выведи список в обычном компоненте (реактивность подключим на шаге 2).

Тип Task — из src/types/task.ts (см. Окружение).

  • makeAutoObservable(this) — в конструкторе превращает поля в observable, геттеры в computed, методы в action. Один вызов вместо ручного перечисления — рекомендуемый способ в MobX 6.
  • Actions — методы, изменяющие состояние. В MobX мутация разрешена (push, присваивание), но её место — внутри action. makeAutoObservable помечает методы как actions автоматически.
  • Прямое присваивание вместо spread — в отличие от React, не нужно создавать новый массив. this.tasks.push(task) корректно: MobX отслеживает мутацию наблюдаемого массива.
Показать эталонную реализацию
import { makeAutoObservable } from 'mobx';
import type { Task } from '../types/task';
export class TaskStore {
tasks: Task[] = [];
constructor() {
// поля → observable, геттеры → computed, методы → action
makeAutoObservable(this);
}
// actions: меняем состояние напрямую (мутация разрешена внутри action)
addTask(title: string) {
const trimmed = title.trim();
if (!trimmed) return;
this.tasks.push({
id: crypto.randomUUID(),
title: trimmed,
done: false,
createdAt: Date.now(),
});
}
removeTask(id: string) {
this.tasks = this.tasks.filter((t) => t.id !== id);
}
toggleTask(id: string) {
const task = this.tasks.find((t) => t.id === id);
if (task) task.done = !task.done; // мутация поля наблюдаемого объекта — ОК
}
}
// Один экземпляр на приложение
export const taskStore = new TaskStore();

Временный компонент (реактивность добавим на шаге 2 через observer):

import { taskStore } from '../stores/TaskStore';
export function TaskListPreview() {
return (
<ul>
{taskStore.tasks.map((task) => (
<li key={task.id}>{task.title}</li>
))}
</ul>
);
}

Дальше — Шаг 2: computed и observer: добавим фильтры, счётчики и сделаем компоненты реактивными.