Нашим прикладом буде застосунок, який дає змогу записувати список покупок — такий собі типовий туду-ліст. Стан нашого застосунку може бути відображений так:
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": "Помідори"
}
]
}