状态革新: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.* 调用。
使用方法
- 粘贴 store 状态的 JSON 快照。
- 检查 t.model({...}) 输出;对象数组包含一个由所有元素合并而成的内联 t.model。
- 复制它,添加 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。