组合
组合的目标是“复用节点身份”,而不是“复制节点值”。
link(node):把已有 IO 节点挂接到新树中。- 结果:引用身份保持一致,更新可沿路径冒泡。
- 场景:跨模块复用状态、拼装视图树、共享同一源状态。
- 你已经有独立 Unit/Tree,希望挂到新的结构中复用。
- 你需要多个树观察同一个状态源。
- 你希望保留原节点语义(订阅、快照、更新日志)。
核心 API
Section titled “核心 API”import { io } from '@iostore/store';import { link } from '@iostore/store/extensions';
const count = io(0);const store = io({ count: link(count) });
store.count === count; // trueimport { io } from '@iostore/store';import { link } from '@iostore/store/extensions';
const profile = io({ name: 'Ada' });const pageState = io({ user: link(profile), tab: 'overview',});
pageState.user.name.set('Lin');console.log(profile.name.get()); // 'Lin'- 身份保持:
linked === original。 - 快照透传:父树
snapshot()可读到被引用节点当前值。 - 更新冒泡:子节点更新会携带父路径前缀向上通知。
- 数组复用:同一节点在数组中重复出现,会映射到多个索引路径。
- 直接把 IO 节点当普通对象塞进树:应使用
link()。 - 在组合关系中引入循环引用:会导致路径和调试复杂化。
- 跨边界随意写入:缺乏写入约束会让状态来源不清晰。
- 在模块边界约定“谁负责写入”。
- 对外暴露组合结果时,优先暴露稳定路径 Unit。
- 复杂组合先画出依赖关系,再实现
link(),避免隐性耦合。