跳到主要内容

状态革新:JSON To MobX State Tree模型 — Numio

把 JSON 快照转换为 MobX-State-Tree 模型定义 const myModel = t.model({...})。对象变为 t.model,数组变为根据所有元素构建的 t.array(...),在部分元素中缺失或为 null 的键变为 t.maybe 或 t.maybeNull。

根据现有 API 响应或已保存的快照快速搭建 store 模型。

JSON

MobX-State-Tree Model

适用场景

  • 根据现有 API 响应或已保存的快照快速搭建 store 模型。
  • 把普通 observable 状态迁移到 MobX-State-Tree,而无需手写每个 types.* 调用。

使用方法

  1. 粘贴 store 状态的 JSON 快照。
  2. 检查 t.model({...}) 输出;对象数组包含一个由所有元素合并而成的内联 t.model。
  3. 复制它,添加 import { types as t } from "mobx-state-tree",再加上 identifier、action 和 view。

JSON 快照

{
  "filter": "all",
  "selectedId": null,
  "todos": [
    { "id": 1, "title": "Write docs", "done": false, "tags": ["work"] },
    { "id": 2, "title": "Ship", "done": true, "dueAt": null }
  ]
}

MobX-State-Tree 模型

const myModel = t.model({
  filter: t.string,
  selectedId: t.frozen(),
  todos: t.array(
    t.model({
      id: t.number,
      title: t.string,
      done: t.boolean,
      tags: t.maybe(t.array(t.string)),
      dueAt: t.maybe(t.frozen()),
    }),
  ),
})

功能与限制

在浏览器的 Web Worker 中运行,不会上传任何内容。输出用 Prettier 格式化。

null 与实际值同时出现时得到 t.maybeNull(type);始终为 null 的值以及空数组的元素变为 t.frozen(),它接受任何可序列化的值。

数组中部分元素缺少的键变为 t.maybe(...)。混合类型数组使用 t.union,例如 t.array(t.union(t.number, t.string))。

不会把 ID 识别为 types.identifier,也不会生成 t.optional 默认值、action 或 view。

FAQ

JSON 的根节点可以是数组吗?

可以。结果变为 t.array(t.model({...})),合并所有元素的键;部分元素缺少的键用 t.maybe 包裹。

为什么我的 id 字段是 t.number 而不是 identifier?

转换器只看值的类型。如果需要按 id 引用或协调(reconciliation),请改为 t.identifier 或 t.identifierNumber。

输入中可以包含函数吗?

不是合法 JSON 的输入会改为按 JavaScript 对象字面量解析,因此函数表达式会变为 t.frozen。这种模式下每个数组只使用第一个元素,所以建议输入 JSON。

规范与参考资料