Store

Flux 通过其工具库flux/utils提供了三个工具类以方便编写比较基础的 State 数据管理逻辑。Store就是其中之一。Flux 中的 Store 主要需要提供数据缓存、数据存取、响应分发的 Action 等功能,并且需要在响应分发时发送数据更改事件以使使用 Store 中数据的模块能够及时进行数据刷新。

Store类在实际项目中一般作为自定义 Store 类的基类使用。Store类提供了以下方法来完成 Store 功能。

  • constructor(dispatcher),创建 Store 实例并将自身绑定至 Dispatcher。
  • addListener(callback),向自身绑定一个监听回调函数,当 Store 中的数据发生改变时会调用这个回调函数。该方法会返回一个函数用来移除监听回调。
  • getDispatcher(),返回自身绑定到的 Dispatcher。
  • getDispatchToken(),返回自身注册在 Dispatcher 上可用于 Dispatcher 上的waitFor()方法的 ID。
  • hasChanged(),在响应 Action 分发时用来判断其中内容是否发生了改变。
  • __emitChange(),用于通知所有监听回调数据已经发生了改变。这个方法不需要手动调用。
  • onDispatch(payload),用于响应 Dispatcher 的 Action 分发,在实现自定义 Store 时必须重写这个方法以实现数据更新逻辑。

在日常使用中,并不会直接使用Store类作为基类来实现自定义 Store,而是会使用Store类的派生类ReduceStore类作为自定义 Store 的基类。ReduceStore类在Store类基础上增加了以下方法来方便 State 的管理。

  • getState(),返回当前 Store 中保存的 State。如果自定义 Store 中保存的不是不可变数据,那么最好重写这个方法。
  • getInitialState(),创建 State 的初始状态,一般在自定义 Store 进行构建时调用。
  • reduce(state, action),响应 Dispatcher 分发 Action,并且对内部保存的 State 进行变更。自定义 Store 类需要重写这个方法,并且保证这个方法是纯函数,不产生任何副作用。这个方法需要返回新的 State。
  • areEqual(one, two),判断两个版本的 State 是否相同。如果使用不可变数据来保存 State 则不需要重写这个方法。

在使用ReduceStore类作为基类时,不需要手动发送数据发生变更的事件。如果需要手动控制数据发生变更事件的发送,可以通过重写areEqual()方法来实现。

以下给出一个使用ReduceStore类实现自定义 Store 的示例。

class CargoStore extends ReduceStore {
  getInitialState() {
    return {
      cargos: []
    };
  }

  reduce(state, action) {
    switch (action.type) {
      case 'add_cargo':
        state.cargos.push(action.payload);
        return state;
      default:
        return state;
    }
  }
}

这个示例中依旧没有使用不可变数据来控制 State,在实际项目中依旧建议使用 Immutable 等功能库来保证 State 中的内容是完全确定的。