前言:app
在項目中,模塊過多,dva使用namespace分離模塊後,若沒有在模塊卸載後清除對應的數據,下次進入時,有可能會有上一次數據的殘留。函數
好比詳情頁,從A商品的詳情頁離開後,返回選擇B商品進入,此時在B商品信息加載以前可能存在A的殘留信息。spa
諸如此類,若模塊過多,須要在每一個模塊的WillUnmount中去clear又太麻煩。code
方法:對象
在model層擴展。大概思路以下:blog
在model-extend.js中配置各類擴展model的[enhanceItems]對象,裏面存儲各類擴展model的function,這些function接收來自model的參數,而後返回一個接受model,返回擴展後的model的函數。ip
返回上面的需求,在enhanceItems裏配置一個enhanceClear,而後監聽路由的變化,在知足條件的時候,dispatch(clear)路由
僞代碼: enhanceItems = { enhance1, enhance2 } enhance1 = (param) => { .....//擴展 return model => newModel }
show me the codeget
// model.js enhanceModel({ enhanceClear: { reg: /\/detail/, clearReducer: { type: 'clearDetail' }, }, })(model) // utils/model-extend.js const enhanceClear = (param) => { const { reg, clearReducer } = param; if (reg && clearReducer) { const clearWrapped = (subscriber) => { // 包裝clearWrapped return (props) => { const { dispatch, history } = props; history.listenBefore(({ pathname }) => { // 監聽跳轉前的動做 const isout = reg.test(history.getCurrentLocation().pathname) && !reg.test(pathname); isout && dispatch(clearReducer); }); subscriber({ ...props }); }; }; return (model) => {
if (!model.subscriptions) model.subscriptions = { setup() {} };
model.subscriptions.setup = clearWrapped(model.subscriptions.setup || (() => {}));
return model;
};
} return model => model;// 若沒有相應參數,則返回原數據函數 }; const enhanceItems = { enhanceClear, }; export const enhanceModel = (param) => { const enhanceFuns = []; Object.keys(param).forEach((key) => { enhanceItems[key] && enhanceFuns.push(enhanceItems[key](param[key])); }); return (model) => { if (enhanceFuns.length === 0) return model; return enhanceFuns.reduce((newModel, fun) => { return (typeof fun === 'function') ? fun(newModel) : newModel; }, model); }; };