定义数据存储

基于 Flux 定义的概念,Store 是用来将逻辑和 State 从组件中移出的可独立测试单元。所以在定义 Store 的时候,通常可以将其分为两种:领域 Store 和 UI Store。

应用中可能会包含一个或者多个领域 Store,这些 Store 保存着应用的所有数据,例如用户、订单等。领域 Store 一般与应用中的业务概念一一对应,一个 Store 通常都会被组织成一个树状结构,每个树状结构中会包含多个领域对象。不同领域对象组合成 Store 的经验是:如果两个事物之间是包含关系,那么它们通常应该存放在一个 Store 里。从这条经验出发,Store 实际上是在管理 领域对象。

领域 Store 一般都需要具备以下职责:

  • 实例化领域对象,确保领域对象知道其归属 Store。
  • 确保每个领域对象只有一个实例。
  • 提供服务后端集成,用以存储数据和更新领域对象实例。
  • 控制领域 Store 自身为单例。

每个领域对象都需要声明自己的类,而且没有必要把 State 当作是数据库来使用。领域对象可以直接引用其他 Store 中的领域对象,我们只需要保证操作和视图足够简单即可。

Tip

领域对象中不应该包含通信方法,所有的通信方法可以抽象出去形成独立的通信层。

领域对象还需要持有一个 Store 实例的引用,这样可以方便与 Store 中的其他领域对象进行通信,在标注 Store 引用时,可以将其标记为 false 以使 MobX不关注 Store 引用的变化。

UI Store 相对于领域 Store 来说就非常具体了,而且 UI Store 一般没有多少逻辑,只会存储大量关于 UI 的松散信息。例如以下这些内容通常都是放置在 UI Store 中的。

  • Session 信息。
  • 应用加载阶段的信息。
  • 影响全局 UI 的信息,例如窗口尺寸、可访问性、语言、主题等。
  • 会影响多个组件的界面 State,例如当前选中项、通用组件可见性、向导、全局遮罩层等。

在构建 Store 的时候,一般需要解决的问题是多个 Store 要如何组合在一起?Store 之间如何相互通信?为了解决这个问题,一般可以通过创建一个 RootStore 来解决,也就是把所有的 Store 都实例化,并共享引用在一个 RootStore 中。这种模式易于设置,而且全局只存在一个 RootStore 的实例,实例控制和单元测试都会比较简单一些。RootStore 一般会通过 Context 插入到组件树的根上,来使得应用全局都可以访问。