Шаг 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 (см. Окружение).
Какие API и зачем
Заголовок раздела «Какие API и зачем»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: добавим фильтры, счётчики и сделаем компоненты реактивными.