Mobx state tree - quản lý state theo một cách mới lạ

Mobx state tree - một cách dùng nâng cao của mobx

Lời nói đầu

Trước đó mình đã giới thiệu cho các bạn hai bài về Mobx (part 1 và part 2) bạn đều có thể tìm kiếm trên blog của mình. Bước kế tới mình sẽ giới thiệu cho các bạn một công cụ hữu ích mà những người dùng mobx nên dùng đó là mobx-state-tree. Một công cụ giúp chúng ta code mobx trở nên đơn giản và rõ ràng hơn rất nhiều, ngoài ra còn rất nhiều chức năng được bổ sung để chúng ta dùng

Mobx state tree là gì?

Bản chất nó chính là dùng mobx nhưng theo một cách khác, cụ thể hơn, mst team họ gọi cách đó là living tree (một cây state sống). Ở các cây sẽ có các node con, có một cấu trúc định nghĩa và xử lý dữ liệu một cách rõ ràng hơn

Types, models, trees & state

Tree = type + state + 💟

Mỗi node trong một cây được miêu tả bởi hai thứ: type (kiểu/ hình thù của dữ liệu) và dữ liệu hiện tại

Một node cơ bản được biểu diễn như sau

import { types } from "mobx-state-tree"

// Khai báo một node Todo, với kiểu dữ liệu được quy định trong types.model
const Todo = types.model({
    title: types.string
})

// Tạo một cây state dựa trên kiểu Todo đã khai báo ở trên
const coffeeTodo = Todo.create({
    title: "Get coffee"
})

Lưu ý: types.model thường được dùng để khai báo một object

Tạo models

const TodoStore = types
    // 1
    .model("TodoStore", {
        loaded: types.boolean, // 2
        endpoint: "http://localhost", // 3
        todos: types.array(Todo), // 4
        selectedTodo: types.reference(Todo) // 5
    })
    .views(self => {
        return {
            // 6
            get completedTodos() {
                return self.todos.filter(t => t.done)
            },
            // 7
            findTodosByUser(user) {
                return self.todos.filter(t => t.assignee === user)
            }
        }
    })
    .actions(self => {
        return {
            addTodo(title) {
                self.todos.push({
                    id: Math.random(),
                    title
                })
            }
        }
    })

Mình sẽ giải thích từng đoạn code sau như sau

  1. // 1 là một kiểu dữ liệu, bạn có thể coi như kiểu dữ kiệu nguyên thuỷ, như types.boolean chẳng hạn (xem //2), nếu phức tạp hơn bạn hãy xem ở //4
  2. //2//3 Kiểu dữ liệu nguyên thuỷ boolean và string
  3. //4 khai báo một array với type là các nốt Todo, có thể hiểu nó là branch
  4. //5 là kiểu dữ liệu tham chiếu, kiểu này rất khó nói nhưng đại khái nó sẽ tham chiếu tới một node Todo nằm trong array todos nhé (về sau mình sẽ gửi code sanbox để các bạn tiện xem)
  5. Nếu các bạn làm việc với mobx rồi thì bạn sẽ quen với computed value, nó sẽ trả về dữ liệu khi mà một trong các giá trị của self thay đổi, sự khác biệt lớn nhất giữa //6//7//6 không nhận param truyền vào còn //7 thì có nhận

Các bạn có thể xem thêm type ở đây

Thế nào là Tree

Khái niệm MST tree thật khó hiểu phải không? Mình sẽ giải thích một vài khái niệm để bạn hiểu rõ hơn

  1. Mỗi object trong MST tree là một node, mỗi dữ liệu nguyên thuỷ sẽ được gọi là
  2. MST chỉ có 3 kiểu dữ liệu của node là: model, array, map
  3. Một node chỉ được tồn tại duy nhất trên một cây. Điều này đảm bảo tính duy nhất và xác định vị trí của node trên cây
  4. Một object có thể truy cập tới một object khác trong cùng 1 cây thông qua `types.references
  5. Không giới hạn có bao nhiêu cây trong MST trees
  6. Nếu môt node trên cây bị thay thế bởi node khác, thì node bị thay thế sẽ trở lên vô dụng
  7. Nếu muốn tạo một node mới dựa trên node đã tồn tại bạn có thể detach node đó hoặc clone

Kết luận

Các bạn có cảm thấy hay không ạ? So với việc dùng mobx thường ta dùng cách này thì code sẽ rõ ràng và nhìn dễ hiểu cũng như dễ maintain hơn hẳn, tuy nhiên code sẽ bị dài hơn (vì nó đi cùng sự rõ ràng)

Mình định gửi cho các bạn code sanbox để học tập theo nhưng có lẽ để bài sau vì bài này mình chỉ muốn giới kiến thức sơ qua về Mobx state tree.

Hẹn các bạn ở bài vết sau nhé. Thanks 💕

Comments

Contact for work:Skype
Code from my 💕