React--Redux異步流

Redux-thunk
import axios from 'axios';
import { 
        ISLOADING,
        ERRORS,
        GETDATA 
    }from '../constants/actionTypes'

let request = (type, params) => {return {type, params}}
let receive = (type, data) => {return {type, data}}

 export  function getList(params){
    return async dispatch => {
        dispatch(request(ISLOADING,params))
        try {       
            let res = await axios.post('localhost:8080/getdatas',params)
            dispatch(receive(GETDATA,{payload:res})
        }catch (err){
            dispatch(receive(ERRORS, {status: 2, errmsg: '數(shù)據(jù)錯(cuò)誤'}))
        }
    }
}

上面代碼中,getList是一個(gè)Action Creator(動(dòng)作生成器),返回一個(gè)函數(shù)。這個(gè)函數(shù)執(zhí)行后,先發(fā)出一個(gè)Action(request(ISLOADING,params)),然后進(jìn)行異步操作。拿到結(jié)果后,然后再發(fā)出一個(gè) Action(receive(GETDATA,{payload:res})。
getList返回了一個(gè)函數(shù),而普通的 Action Creator 默認(rèn)返回一個(gè)對(duì)象。
使用Redux-thunk

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducer from './reducers';

const store = createStore(
  reducer,
  applyMiddleware(thunk)
);

上面代碼使用redux-thunk中間件,改造store.dispatch,使得后者可以接受函數(shù)作為參數(shù)。
使用redux-thunk的最大問題就是太復(fù)雜了,重復(fù)的模板代碼太多。

redux-promise

由于redux-thunk寫起來實(shí)在是太麻煩了,redux-promise出現(xiàn)了,
它自定義了一個(gè)middleware,當(dāng)檢測到有action的payload屬性是Promise對(duì)象時(shí),就會(huì):
若resolve,觸發(fā)一個(gè)此action的拷貝,但payload為promise的value,并設(shè)status屬性為”success”
若reject,觸發(fā)一個(gè)此action的拷貝,但payload為promise的reason,并設(shè)status屬性為”error”

import axios from 'axios';
import { 
        GETDATA 
} from '../constants/actionTypes'

let request = (type, params) => {return {type, params}}
let receive = (type, data) => {return {type, data}}

 export  function getList(params){  
    return {
          type: GETDATA,
          payload: axios.post(url,params) 
    }
}

代碼量明顯減少。
redux-promise雖然在代碼量上減少,但是,它太過精簡了,結(jié)果我們不能在拿到數(shù)據(jù)前,做任何操作。
使用redux-thunk,在請(qǐng)求數(shù)據(jù)前,先發(fā)一個(gè)action,我們可以根據(jù)這個(gè)action做出操作,但是promise卻不行。
最初觸發(fā)的action被中間件攔截然后過濾掉了。原因很簡單,redux認(rèn)可的action對(duì)象是簡單對(duì)象,而在redux-promise中,初始action的payload是個(gè)Promise。

redux-promise-middleware

redux-promise-middleware相比redux-promise,采取了更為溫和和漸進(jìn)式的思路,保留了和redux-thunk類似的三個(gè)action。

import axios from 'axios';
import { 
        GETDATA 
} from '../constants/actionTypes'

let request = (type, params) => {return {type, params}}
let receive = (type, data) => {return {type, data}}

 export  function getList(params){  
    return {
          type: GETDATA,
          payload: {
              promise:  axios.post(url,params) 
          }
     }
}

reduces:

const reducer = function(state, action) {
    switch(action.type) {
    case GET_DATA_PENDING :
        return state; 
    case GET_DATA_FULFILLED : 
        return {
        ...state,
        isInitialized: true
      };
    case GET_DATA_REJECTED : 
        return {
        ...state,
        isInitialized: false
      };
    }
}

redux-promise-middleware,為action提供了三個(gè)type,_PENDING、_FULFILLED、_REJECTED,代表了不同狀態(tài)。
它的遺憾則是只在action層實(shí)現(xiàn)了簡化,對(duì)reducer層則束手無策。另外,相比redux-thunk,它還多出了一個(gè)_PENDING的字符串模板代碼(三個(gè)action卻需要四個(gè)type)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容