Redux高級篇

前言

在前面的基礎篇,咱們學習了一些redux的基礎使用和基本方法的實現,可是這些基礎的使用並不能知足咱們的平常開發的須要,本文將給你們帶來一些更高級的用法與實現。redux

高級使用

applyMiddleware

在開發的過程當中每每咱們須要在dispatch以前增長一些本身的代碼邏輯,也就是須要咱們使用中間件,在redux的設計中就考慮到了這個事情,因此爲咱們提供了applyMiddleware這個方法。app

中間件思想模擬(aop切片思想)

  • 【1】保存原有的dispatch方法
  • 【2】重寫store中的dispatch方法
  • 【3】在重寫的dispatch方法中插入本身的邏輯
  • 【4】在重寫的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的執行過程,並實現一下
    • 【1】applyMiddleware傳入一箇中間件執行返回一個函數(fn1)
    • 【2】返回的函數(fn1)傳入createStore執行又返回函數(fn2)
    • 【3】返回的函數(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(結合中間件思想模擬)
      • 【1】接收的參數能夠解構出getStatedispatch方法,返回fn1
        • 【1-1】回想一下咱們基礎篇中哪裏有這個方法?沒錯就是建立的store
      • 【2】返回的fn1接收參數next
        • 【2-1】經過最後的next(action),咱們再回想一下基礎篇中的哪一個方法執行須要傳入action?對的,就是diapatch,這裏咱們能夠先假象成這個next就是咱們保存的原始dispatch
      • 【3】最後返回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)
        }
    }
}
複製代碼

compose的講解設計

相關文章
相關標籤/搜索