functioncombineReducersWithImmer(reducers: ReducersMapObject){constreducersWithImmer: ReducersMapObject<any,Action<any>>={};// reducer must return value because literal don't support immer
for(constkeyofObject.keys(reducers)){constreducerFn=reducers[key];reducersWithImmer[key]=(state,payload)=>typeofstate==="object"?produce(state,(draft: Models)=>{constnext=reducerFn(draft,payload);if(typeofnext==="object")returnnext;}):reducerFn(state,payload);}returncombineReducers(reducersWithImmer);}// rematch plugin
constimmerPlugin=():Plugin=>({config:{redux:{combineReducers: combineReducersWithImmer,},},});
exportdefault(config: LoadingConfig={}):Plugin=>{// ... 上述的初始化代码
return{config:{models:{loading,},},onModel({name}:Model){// do not run dispatch on "loading" model
if(name===loadingModelName){return;}cntState.models[name]=0;loading.state.models[name]=converter(cntState.models[name]);loading.state.effects[name]={};constmodelActions=this.dispatch[name];// map over effects within models
Object.keys(modelActions).forEach((action: string)=>{if(this.dispatch[name][action].isEffect!==true){return;}cntState.effects[name][action]=0;loading.state.effects[name][action]=converter(cntState.effects[name][action]);constactionType=`${name}/${action}`;// ignore items not in whitelist
if(config.whitelist&&!config.whitelist.includes(actionType)){return;}// ignore items in blacklist
if(config.blacklist&&config.blacklist.includes(actionType)){return;}// copy orig effect pointer
constorigEffect=this.dispatch[name][action];// create function with pre & post loading calls
consteffectWrapper=async(...props)=>{try{this.dispatch.loading.show({name,action});// waits for dispatch function to finish before calling "hide"
consteffectResult=awaitorigEffect(...props);this.dispatch.loading.hide({name,action});returneffectResult;}catch(error){this.dispatch.loading.hide({name,action});throwerror;}};effectWrapper.isEffect=true;// replace existing effect with new wrapper
this.dispatch[name][action]=effectWrapper;});},};};
还是分三步来看:
首先,由于 plugin 导出的 model 也会经过 onModel 钩子处理,因此先排除 loading model 自身。然后对 state.models 初始化,以及从 this.dispatch 中取得该 model 的所有 action。