Skip to content

Latest commit

 

History

History
112 lines (88 loc) · 4.85 KB

03_models.md

File metadata and controls

112 lines (88 loc) · 4.85 KB

Моделі та типи

Нашим прикладом буде застосунок, який дає змогу записувати список покупок — такий собі типовий туду-ліст. Стан нашого застосунку може бути відображений так:

const state = {
  list: [
    { id: '4fa51175-9de1-473f-961e-c9f485b0ed4d', title: 'Яйця' },
    { id: '8c70682f-5aa1-4206-a5dc-6ba25902f916', title: 'Помідори' },
  ],
};

Тобто весь наш стан — об'єкт, в якому буде поле list, яке буде масивом, в якому ми будемо зберігати наші задачі, кожна з яких — об'єкт із полями id (яке в нас буде uuid)та title.

Давайте спершу розберемось з тим, що нам робити з кожним об'єктом задачі, як їх створювати динамічно, і як змінювати їх стан. Якщо б ми це реалізовували на es6 класах, можна було б створити клас, який би нам дозволяв створювати нові задачі:

class TodoModel {
  constructor(id, title) {
    this.id = id;
    this.title = title;
  }

  // не забуваємо про те, що нам потрібно їх серіалізувати в JSON
  toJSON() {
    return {
      id: this.id,
      title: this.title,
    };
  }
}

const todo = new TodoModel(uuid(), 'Петрушка');

// ця функція нам дозволить красиво виводити в консоль
// будемо її використовувати і надалі
function prettyPrint(obj) {
  console.log(JSON.stringify(obj, null, 2));
}
prettyPrint(todo)

Результатом виконання буде такий json:

Зверніть увагу: зараз і в подальшому поле id може відрізнятись, так як ми використовуємо uuid, а він генерує кожного разу унікальне значення

{
  "id": "82d83415-e09d-4966-a139-71d6ab30bee9",
  "title": "Петрушка"
}

Проте ми хочемо будувати дерево, тому нам потрібно використовувати ті API та підходи, які надає нам mobx-state-tree. А в цій бібліотеці для того щоб створити об'єкт (клас), нам потрібно створити модель, використовуючи types:

import { types } from 'mobx-state-tree';

const MyModel = types.model({});

Для того щоб позначити які поля в нас є, а також який в них має бути тип, щоб MST їх перевіряла на валідність, types має безліч інших полів/методів, тобто модель нашої задачі буде:

const TodoModel = types.model({
  id: types.string,
  title: types.string,
})

Валідація — перевірка типів — відбувається як при створенні моделі, так при applySnapshot, про який ми поговоримо згодом. Валідація, звісно ж, не працює при NODE_ENv=production

Зважаючи на те, що у нас list — масив, types має відповідний тип і для цього — types.array, тому модель стану нашого застосунку буде наступна:

const TodoListModel = types.model({
  list: types.array(TodoModel),
});

І щоб запустити це все, виконаємо такі дії:

// створюємо нашу модель, прокидаючи їй стейт, який ми оголосили вище
// зверніть увагу, що ми не використовуємо `new`
// для того щоб створити модель, ми використовуємо статичний метод `create`
// який приймає снепшот для цієї моделі — деякий стан, який підпадає під
// опис типу, що ми вказали при створенні моделі
const todoList = TodoListModel.create(state);

// виводимо її снепшот:
prettyPrint(todoList);

Результатом виконання буде такий ж об'єкт, який ми оголосили як state:

{
  "list": [
    {
      "id": "4fa51175-9de1-473f-961e-c9f485b0ed4d",
      "title": "Яйця"
    },
    {
      "id": "8c70682f-5aa1-4206-a5dc-6ba25902f916",
      "title": "Помідори"
    }
  ]
}