插件系统
rematch实现了一个插件系统,内置了dispatch和effects两个插件,分别用来增强dispatch和处理异步操作。rematch的插件,要符合rematch的要求,每个插件返回一个对象,这个对象可以包含几个属性,用来在不同的生命周期中对store进行操作。
对于每一个插件对象,提供了如下几个属性进行配置。
- onInit:进行插件的初始化工作
- config: 对rematch进行配置,会在rematch初始化之前,对插件的config配置进行merge操作
- exposed:暴露给全局的属性和方法,可以理解为占位符,用于数据的共享
- middleware:相当于redux的中间键,如果提供了这个属性,会把它交给redux进行处理
- onModel:加载model的时候会调用的方法,用来对model进行处理
- onStoreCreated:当rematch的store对象生成后,调用的方法,生成最终的store对象
DispatchPlugin
plugin包含exposed、onStoreCreated和onModel三个属性
const dispatchPlugin: R.Plugin = {
exposed: {
storeDispatch(action: R.Action, state: any) {
console.warn('Warning: store not yet loaded')
},
storeGetState() {
console.warn('Warning: store not yet loaded')
},
dispatch(action: R.Action) {
return this.storeDispatch(action)
},
createDispatcher(modelName: string, reducerName: string) {
return async (payload?: any, meta?: any): Promise<any> => {
const action: R.Action = { type: `${modelName}/${reducerName}` }
if (typeof payload !== 'undefined') {
action.payload = payload
}
if (typeof meta !== 'undefined') {
action.meta = meta
}
return this.dispatch(action)
}
},
},
// 在store创建完成的时候调用,将增强后的dispatch方法抛出
onStoreCreated(store: any) {
this.storeDispatch = store.dispatch
this.storeGetState = store.getState
return { dispatch: this.dispatch }
},
// 对model上的每个reducer创建action createor,并挂载到dispatch对象上
onModel(model: R.Model) {
this.dispatch[model.name] = {}
if (!model.reducers) {
return
}
for (const reducerName of Object.keys(model.reducers)) {
this.validate([
[
!!reducerName.match(/\/.+\//),
`Invalid reducer name (${model.name}/${reducerName})`,
],
[
typeof model.reducers[reducerName] !== 'function',
`Invalid reducer (${model.name}/${reducerName}). Must be a function`,
],
])
this.dispatch[model.name][reducerName] = this.createDispatcher.apply(
this,
[model.name, reducerName]
)
}
},
}
复制代码
这个插件用来处理model的reducers属性,如果model没有reducers,就直接退出;否则,遍历reducers,如果键名包含是/符号开头结尾的或者值不是一个函数,就报错退出。
通过createDispatcher函数,对每个reducer进行处理,包装成一个异步的action creator,action的type由model.name和reducerName组成。
onStoreCreated属性,会返回增强后的dispatch方法去重置redux默认的dispatch方法。
EffectsPlugin
effects plugin包含exposed、onModel和middleware三个属性。
const effectsPlugin: R.Plugin = {
exposed: {
effects: {},
},
// 将每个mode