dojo dragon main logo

Store 概念详解

State 对象

在现代浏览器中,state 对象是作为 CommandRequest 的一部分传入的。对 state 对象的任何修改都将转换为相应的 operation,然后应用到 store 上。

import { createCommandFactory } from '@dojo/framework/stores/process';
import { State } from './interfaces';
import { remove, replace } from '@dojo/framework/stores/state/operations';

const createCommand = createCommandFactory<State>();

const addUser = createCommand<User>(({ payload, state }) => {
	const currentUsers = state.users.list || [];
	state.users.list = [...currentUsers, payload];
});

注意,IE 11 不支持访问 state,如果尝试访问将立即抛出错误。

StoreProvider

StoreProvider 接收三个属性

  • renderer: 一个渲染函数,已将 store 注入其中,能访问状态并向子部件传入 process。
  • stateKey: 注册状态时使用的 key 值。
  • paths (可选): 将此 provider 连接到状态的某一局部上。

失效

StoreProvider 有两种方法触发失效并促使重新渲染。

  1. 推荐的方式是,通过向 provider 传入 paths 属性来注册 path,以确保只有相关状态变化时才会失效。
  2. 另一种是较笼统的方式,当没有为 provider 定义 path 时,store 中的 任何 数据变化都会引起失效。

Process

生命周期

Process 有一个执行生命周期,它定义了所定义行为的流程。

  1. 如果存在转换器,则首先执行转换器来转换 payload 对象
  2. 按顺序同步执行 before 中间件
  3. 按顺序执行定义的 command
  4. 在执行完每个 command (如果是多个 command 则是一块 command)之后,应用命令返回的 operation
  5. 如果在执行命令期间抛出了异常,则不会再执行后续命令,并且也不会应用当前的 operation
  6. 按顺序同步执行 after 中间件

Process 中间件

使用可选的 beforeafter 方法在 process 的前后应用中间件。这允许在 process 所定义行为的前和后加入通用的、可共享的操作。

也可以在列表中定义多个中间件。会根据中间件在列表中的顺序同步调用。

Before

before 中间件块能获取传入的 payloadstore 的引用。

middleware/beforeLogger.ts

const beforeOnly: ProcessCallback = () => ({
	before(payload, store) {
		console.log('before only called');
	}
});

After

after 中间件块能获取传入的 error (如果发生了错误的话)和 process 的 result

middleware/afterLogger.ts

const afterOnly: ProcessCallback = () => ({
	after(error, result) {
		console.log('after only called');
	}
});

result 实现了 ProcessResult 接口,以提供有关应用到 store 上的变更信息和提供对 store 的访问。

  • executor - 允许在 store 上运行其他 process
  • store - store 引用
  • operations - 一组应用的 operation
  • undoOperations - 一组 operation,用来撤销所应用的 operation
  • apply - store 上的 apply 方法
  • payload - 提供的 payload
  • id - 用于命名 process 的 id

订阅 store 的变化

Store 有一个 onChange(path, callback) 方法,该方法接收一个或一组 path,并在状态变更时调用回调函数。

main.ts

const store = new Store<State>();
const { path } = store;

store.onChange(path('auth', 'token'), () => {
	console.log('new login');
});

store.onChange([path('users', 'current'), path('users', 'list')], () => {
	// Make sure the current user is in the user list
});

Store 中还有一个 invalidate 事件,store 变化时就触发该事件。

main.ts

store.on('invalidate', () => {
	// do something when the store's state has been updated.
});