Redux手藝架構簡介(二)-- 異步完成

申明:對Redux不相識的同硯可先看看這篇文章Redux手藝架構簡介(一)

媒介

這裏說的Redux異步完成,是專指Redux中的異步Action完成,而不是指運用的異步完成,因為Redux自身只支撐同步action,即發送action,state馬上更新;那假如我在發送一個action后,須要state過一段時間再更新呢?按平常的思緒redux是沒法處置懲罰這類狀況的,下面就來看看異步Action是怎樣完成的吧!

須要提的一點是,實在完全能夠將異步邏輯寫在View中,然後在回調函數中發送action。然則假如你要合營react一同運用,如許做就違犯了react-redux的設想頭腦,即UI與邏輯的星散(詳細的完成能夠鄙人一篇文章中看到),而且當存在多個異步請求時也很難將異步邏輯籠統出來,所以異步邏輯應該由Redux架構完成,如許也就必需完成發送異步action了

1. 中間件(Middleware)

為相識決上面提到的題目,我們須要引入中間件的觀點。

(1)機遇

中間件實行的機遇是在action提議以後,reducer實行之前。

《Redux手藝架構簡介(二)-- 異步完成》
即在dispatch一個action以後,經由一系列的中間件處置懲罰歷程,再舉行reducer。

(2)道理

本質上,中間件就是對dispatch函數的革新。當實行dispatch(action)時,會先挪用中間件,舉行一些內部邏輯處置懲罰,如:增添日記等,以後再實行dispatch。假如要支撐中間件的鏈式挪用,必需再返回一個dispatch。
下面是中間件的簡樸完成:

function logger(store) {
  // 這裏的 next 必需指向前一個 middleware 返回的函數:
  const next = store.dispatch

  return function dispatchAndLog(action) {
    console.log('dispatching', action)
    let result = next(action)
    console.log('next state', store.getState())
    return result
  }
}

(3) 在Redux中運用中間件

能夠運用Redux的API—applyMiddleware直接運用中間件,代碼以下:

import {applyMiddleware,createStore} from 'redux';
import {createLogger} from 'redux-logger';//log中間件
import thunk from 'redux-thunk';//將dispatch革新成能夠接收函數作為參數的中間件
import indexPhotomainReducer from '../reducer/indexPhotomainReducer';

const logger = createLogger();
const store  = createStore(
        indexPhotomainReducer,
        applyMiddleware(thunk, logger)
);

因而可知,能夠把applyMiddleware作為createStore的第二個參數傳入,你所運用的中間件須要下載零丁npm包,然後按遞次傳入applyMiddleware函數中(注:中間件有遞次請求,須要看下每一个中間件的運用文檔,logger平常要放在末了)。

2. Redux異步完成

(1) Action設想

須要增添三種action

  • 關照異步請求提議的action
  • 異步請求勝利的action
  • 異步請求失利的action

示例代碼以下:

export const requestPostsAction = () => {
 return {
     type: REQUEST_POSTS
 };
}

export const receivePostsSuccessAction = (data) => {
 return {
     type: RECEIVE_POSTS_SUCCESS,
     data
 };
}
export const receivePostsFailureAction = (error) => {
 return {
     type: RECEIVE_POSTS_FAILURE,
     error
 };
}

返回參數完全能夠自定義。這3種action離別在請求最先前,請求勝利后,請求失利后發送。
## (2) State設想
為了合營異步Action,能夠在state樹中增添2個屬性:

  • isFetching:示意是不是正在處置懲罰異步請求。
  • isValidate:示意數據的有效性,他的作用是在異步請求發送失利后,通知View當前state的數據是過期的數據。

State屬性能夠憑本身喜歡隨便設想。設想好后能夠如許編寫reducer:

let sliderReducer = function (state = initialState, action) {
    switch(action.type){
        case photomainAction.RECEIVE_POSTS_SUCCESS:
               return Object.assign({}, state, {photoData,videoData,isFetching:false,isValidate:true});
        case photomainAction.RECEIVE_POSTS_FAILURE:
               return Object.assign({}, state, {isFetching:false,isValidate:false});
        case photomainAction.REQUEST_POSTS:
               return Object.assign({}, state, {isFetching:true,isValidate:false});
        default:
            return state;
    }
}

(3) redux-thunk中間件

當設想好action和state后,我們想要到達的結果是–能夠像同步一樣dispatch一個action,而不必斟酌異步邏輯。
為了到達這類結果,起首面對的題目是,異步邏輯放在那裡?這裏只要2個挑選:action中或reducer中(store是不適合處置懲罰數據的)。因為reducer必需是一個純函數,他不適合處置懲罰像異步請求如許存在不確定的輸出的邏輯。末了只能放在action中處置懲罰了。
這時刻,為了處置懲罰異步請求,action建立函數須要返回一個帶有異步請求邏輯的函數,而不是一個對象了。而dispatch只能接收對象,不能接收函數作為參數,如許就面對又一個題目:怎樣讓dispatch接收函數?
接下來就是redux-thunk中間件發揮作用的時刻了,他能夠讓dispatch接收一個函數(道理就是上一節講的,他實際上是改寫了dispatch函數),終究異步的action能夠如許完成:

//定義一個action creator – fetchPosts
export const fetchPosts = () => (dispatch, getState) => {
    dispatch(requestPostsAction());
    return window.fetch("/photo/initPage").then(response=>{
            if(response.ok){
                return response.json();
            }else{
                dispatch(receivePostsFailureAction("error"));
            }
        }).then(data => {
            if(data){
                dispatch(receivePostsSuccessAction(data));
            }else{
                dispatch(receivePostsFailureAction("error"));
            }
        });
}

如許就能夠像同步一樣發送action了,即:

dispatch(fetchPosts());

接下來只需悄悄守候view的更新就好了,如許就完成了全部Redux的異步流程。

本篇到此告一段落,下一篇引見React與Redux整合手藝

參考

Redux 中文文檔
Redux 入門教程-阮一峰

    原文作者:brantni
    原文地址: https://segmentfault.com/a/1190000014909801
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞