React中MobX-state-tree的Instance与SnapshotOrInstance类型差异及适用场景
Instance 与 SnapshotOrInstance 的差异及适用场景
先拿一个简单的MST模型示例做基础:
import { types } from "mobx-state-tree"; const UserModel = types.model({ id: types.string, name: types.string, age: types.number }) .actions(self => ({ setAge(newAge: number) { self.age = newAge; } }));
Instance
它是MST模型实际运行时实例的类型,包含模型所有的属性、动作、视图等完整能力。
适用场景
- 声明组件props时,明确接收的是MST实例:
type UserProps = { user: Instance<typeof UserModel>; }; const UserProfile = ({ user }: UserProps) => { return ( <div> <p>Name: {user.name}</p> {/* 直接调用实例的动作,类型提示会自动补全 */} <button onClick={() => user.setAge(user.age + 1)}>Increase Age</button> </div> ); }; - 在MobX的反应式逻辑(比如
autorun、reaction)里操作实例时,用这个类型能获得完整的类型提示,包括动作调用。
SnapshotOrInstance
它是MST实例类型 + 对应快照类型的联合类型。快照是模型的纯数据表示(只有属性,没有动作、视图),相当于模型的JSON版本。
适用场景
- 处理既可能是实例、又可能是快照的数据:比如从API拉取的原始数据(快照)、从localStorage读取的快照,或者函数允许传入两种格式的参数:
import { applySnapshot } from "mobx-state-tree"; function updateUser(target: SnapshotOrInstance<typeof UserModel>, newData: Partial<typeof UserModel.SnapshotType>) { if ("setAge" in target) { // 是实例,直接应用快照更新数据 applySnapshot(target, newData); } else { // 是快照,返回合并后的新纯数据对象 return { ...target, ...newData }; } } - 写通用工具函数时用,避免重复编写实例和快照两种类型的处理逻辑。
核心差异
- 类型范围:
Instance<>只包含模型实例类型,带完整的方法(动作、视图);SnapshotOrInstance<>是实例类型和快照类型的联合,既支持操作实例的方法,也能处理纯数据结构。
- 用途指向:
Instance<>用于明确要操作活的模型实例的场景,依赖反应式更新、需要调用动作;SnapshotOrInstance<>用于需要兼容实例和纯数据快照的场景,比如数据的加载、保存、转换环节。
内容的提问来源于stack exchange,提问作者Lukas
相关产品推荐
相关产品推荐

