在前面的基礎篇,咱們學習了一些
redux
的基礎使用和基本方法的實現,可是這些基礎的使用並不能知足咱們的平常開發的須要,本文將給你們帶來一些更高級的用法與實現。redux
applyMiddleware
在開發的過程當中每每咱們須要在
dispatch
以前增長一些本身的代碼邏輯,也就是須要咱們使用中間件,在redux
的設計中就考慮到了這個事情,因此爲咱們提供了applyMiddleware
這個方法。app
dispatch
方法store
中的dispatch
方法dispatch
方法中插入本身的邏輯dispatch
方法中執行保存的原有dispath
方法注:本文依然使用基礎篇中的
React
實現源碼繼續講解函數
/** * store/index.js */
import { createStore } from 'redux';
import reducers from './reducers';
const store = createStore(reducers);
/*【1】保存原有的dispatch方法*/
const middleWare = store.dispatch;
/*【2】重寫store中的dispatch方法*/
store.dispatch = function(action){
/*【3】在重寫的`dispatch`方法中插入本身的邏輯*/
console.log('老狀態',store.getState());
/*【4】在重寫的`dispatch`方法中執行保存的原有`dispath`方法*/
middleWare(action);
/*【3】在重寫的`dispatch`方法中插入本身的邏輯*/
console.log('新狀態',store.getState());
}
export default store;
複製代碼
經過上一小節的講解我以爲你們應該都明白中間件的做用和基本的思想了,固然在咱們的真正開發中咱們的中間件確定不會像如今這樣寫的豪無逼格,下面我以實例爲你們講解post
/** * store/logger.js */
const logger = ({getState,dispatch})=>next=>action=>{
console.log('老狀態(applyMiddleware)',getState());
next(action);
console.log('新狀態(applyMiddleware)',getState());
}
export default logger;
/** * store/index.js */
import { createStore,applyMiddleware } from 'redux';
import reducers from './reducers';
import logger from './logger';
const store = applyMiddleware(logger)(createStore)(reducers);
export default store;
複製代碼
applyMiddleware
的執行過程,並實現一下
applyMiddleware
傳入一箇中間件執行返回一個函數(fn1
)fn1
)傳入createStore
執行又返回函數(fn2
)fn2
)傳入reducers
執行返回store
function applyMiddleware(middleware) {
/*【1】applyMiddleware傳入一箇中間件執行返回一個函數(`fn1`)*/
return function fn1(createStore) {
/*【2】返回的函數(`fn1`)傳入`createStore`執行又返回函數(`fn2`)*/
return function fn2(reducers) {
/*【3】返回的函數(`fn2`)傳入`reducers`執行返回`store`*/
const store = createStore(reducers);
return store;
}
}
}
複製代碼
上圖爲應用到目前爲止咱們實現的
applyMiddleware
的截圖,能夠看到除了咱們的中間件logger
沒有效果其餘邏輯是能夠跑通的,所以證實咱們的方向是正確的,因此咱們結合logger
繼續完善學習
logger
(結合中間件思想模擬)
getState
和dispatch
方法,返回fn1
store
中fn1
接收參數next
next(action)
,咱們再回想一下基礎篇中的哪一個方法執行須要傳入action
?對的,就是diapatch
,這裏咱們能夠先假象成這個next
就是咱們保存的原始dispatch
action=>{native code}
,包裝後的diapatch
function applyMiddleware(middleware){
return function(createStore){
return function(reducers){
const store = createStore(reducers);
let dispatch = ()=>{throw Error('還不能用')};
const middlewareAPI = {
getState:store.getState,
dispatch:(...args)=>dispatch(args)
}
middleware = middleware(middlewareAPI);
dispatch = middleware(store.dispatch);
return {
...store,
dispatch
};
}
}
}
複製代碼
結合咱們的實現,結果以下 ui
上一小節中咱們僅僅是實現了一箇中間件的狀況,也就是說當咱們有不少事情想在
dispatch
的時候想搞的時候顯然咱們須要多箇中間件配合處理,固然你確定想問,爲何不能把全部的事情放在一箇中間件裏面處理呢,這個也不是不能夠,可是咱們中間件的使用規則通常都是單一邏輯,也就是說一箇中間件只處理一件事情,那麼咱們怎麼將中間件級聯起來呢?spa
/*store/index.js*/
import { createStore,applyMiddleware } from 'redux';
import reducers from './reducers';
import logger from './logger';
import logger1 from './logger1';
const store = applyMiddleware(logger,logger1)(createStore)(reducers);
export default store;
/*store/logger.js*/
const logger = ({ getState, dispacth }) => next => action => {
console.log('老狀態', getState());
next(action);
console.log('新狀態',getState());
}
export default logger;
/*store/logger1.js*/
const logger1 = ({ getState, dispacth }) => next => action => {
console.log('老狀態1', getState());
next(action);
console.log('新狀態1',getState());
}
export default logger1;
複製代碼
function applyMilldeware(...middleware){
return function(createStore){
return function(reducers){
const store = createStore(reducers);
let dispatch = ()=>{thorw Error('不能用')}
const middlewareAPI = {
getState : store.getState;
dispatch : (..args)=>dispatch(args)
}
const chain = middlewares.map(middleware=>middleware(middlewareAPI));
dispatch = compose(...chain)(store.dispatch)
}
}
}
複製代碼