摘要:異步實(shí)現(xiàn)設(shè)計(jì)需要增加三種通知異步請(qǐng)求發(fā)起的異步請(qǐng)求成功的異步請(qǐng)求失敗的示例代碼如下返回參數(shù)完全可以自定義。這種分別在請(qǐng)求開(kāi)始前,請(qǐng)求成功后,請(qǐng)求失敗后發(fā)送。表示數(shù)據(jù)的有效性,他的作用是在異步請(qǐng)求發(fā)送失敗后,告訴當(dāng)前的數(shù)據(jù)是過(guò)時(shí)的數(shù)據(jù)。
說(shuō)明:對(duì)Redux不了解的同學(xué)可先看看這篇文章Redux技術(shù)架構(gòu)簡(jiǎn)介(一)
前言這里說(shuō)的Redux異步實(shí)現(xiàn),是專(zhuān)指Redux中的異步Action實(shí)現(xiàn),而不是指應(yīng)用的異步實(shí)現(xiàn),因?yàn)镽edux本身只支持同步action,即發(fā)送action,state立即更新;那如果我在發(fā)送一個(gè)action后,需要state過(guò)一段時(shí)間再更新呢?按正常的思路redux是無(wú)法處理這種情況的,下面就來(lái)看看異步Action是如何實(shí)現(xiàn)的吧!
需要提的一點(diǎn)是,其實(shí)完全可以將異步邏輯寫(xiě)在View中,然后在回調(diào)函數(shù)中發(fā)送action。但是如果你要配合react一起使用,這樣做就違背了react-redux的設(shè)計(jì)思想,即UI與邏輯的分離(具體的實(shí)現(xiàn)可以在下一篇文章中看到),而且當(dāng)存在多個(gè)異步請(qǐng)求時(shí)也很難將異步邏輯抽象出來(lái),所以異步邏輯應(yīng)該由Redux架構(gòu)實(shí)現(xiàn),這樣也就必須實(shí)現(xiàn)發(fā)送異步action了1. 中間件(Middleware)
為了解決上面提到的問(wèn)題,我們需要引入中間件的概念。
(1)時(shí)機(jī)中間件執(zhí)行的時(shí)機(jī)是在action發(fā)起之后,reducer執(zhí)行之前。
即在dispatch一個(gè)action之后,經(jīng)過(guò)一系列的中間件處理過(guò)程,再進(jìn)行reducer。
本質(zhì)上,中間件就是對(duì)dispatch函數(shù)的改造。當(dāng)執(zhí)行dispatch(action)時(shí),會(huì)先調(diào)用中間件,進(jìn)行一些內(nèi)部邏輯處理,如:添加日志等,之后再執(zhí)行dispatch。如果要支持中間件的鏈?zhǔn)秸{(diào)用,必須再返回一個(gè)dispatch。
下面是中間件的簡(jiǎn)單實(shí)現(xiàn):
function logger(store) { // 這里的 next 必須指向前一個(gè) middleware 返回的函數(shù): 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中應(yīng)用中間件
可以使用Redux的API—applyMiddleware直接使用中間件,代碼如下:
import {applyMiddleware,createStore} from "redux"; import {createLogger} from "redux-logger";//log中間件 import thunk from "redux-thunk";//將dispatch改造成可以接受函數(shù)作為參數(shù)的中間件 import indexPhotomainReducer from "../reducer/indexPhotomainReducer"; const logger = createLogger(); const store = createStore( indexPhotomainReducer, applyMiddleware(thunk, logger) );
由此可見(jiàn),可以把a(bǔ)pplyMiddleware作為createStore的第二個(gè)參數(shù)傳入,你所使用的中間件需要下載多帶帶npm包,然后按順序傳入applyMiddleware函數(shù)中(注:中間件有順序要求,需要看下每個(gè)中間件的使用文檔,logger一般要放在最后)。
2. Redux異步實(shí)現(xiàn) (1) Action設(shè)計(jì)需要增加三種action
通知異步請(qǐng)求發(fā)起的action
異步請(qǐng)求成功的action
異步請(qǐng)求失敗的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 }; }
返回參數(shù)完全可以自定義。這3種action分別在請(qǐng)求開(kāi)始前,請(qǐng)求成功后,請(qǐng)求失敗后發(fā)送。
## (2) State設(shè)計(jì)
為了配合異步Action,可以在state樹(shù)中增加2個(gè)屬性:
isFetching:表示是否正在處理異步請(qǐng)求。
isValidate:表示數(shù)據(jù)的有效性,他的作用是在異步請(qǐng)求發(fā)送失敗后,告訴View當(dāng)前state的數(shù)據(jù)是過(guò)時(shí)的數(shù)據(jù)。
State屬性可以憑自己喜好隨意設(shè)計(jì)。設(shè)計(jì)好后可以這樣編寫(xiě)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中間件
當(dāng)設(shè)計(jì)好action和state后,我們想要達(dá)到的效果是--可以像同步一樣dispatch一個(gè)action,而不用考慮異步邏輯。
為了達(dá)到這種效果,首先面臨的問(wèn)題是,異步邏輯放在哪里?這里只有2個(gè)選擇:action中或reducer中(store是不適合處理數(shù)據(jù)的)。由于reducer必須是一個(gè)純函數(shù),他不適合處理像異步請(qǐng)求這樣存在不確定的輸出的邏輯。最后只能放在action中處理了。
這時(shí),為了處理異步請(qǐng)求,action創(chuàng)建函數(shù)需要返回一個(gè)帶有異步請(qǐng)求邏輯的函數(shù),而不是一個(gè)對(duì)象了。而dispatch只能接受對(duì)象,不能接受函數(shù)作為參數(shù),這樣就面臨又一個(gè)問(wèn)題:如何讓dispatch接受函數(shù)?
接下來(lái)就是redux-thunk中間件發(fā)揮作用的時(shí)候了,他可以讓dispatch接受一個(gè)函數(shù)(原理就是上一節(jié)講的,他其實(shí)是改寫(xiě)了dispatch函數(shù)),最終異步的action可以這樣實(shí)現(xiàn):
//定義一個(gè)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")); } }); }
這樣就可以像同步一樣發(fā)送action了,即:
dispatch(fetchPosts());
接下來(lái)只需靜靜等待view的更新就行了,這樣就實(shí)現(xiàn)了整個(gè)Redux的異步流程。
本篇到此告一段落,下一篇介紹React與Redux整合技術(shù)。
參考Redux 中文文檔
Redux 入門(mén)教程-阮一峰
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95078.html
摘要:是一個(gè)程序架構(gòu),源于提出的一種架構(gòu),然而,它不僅可以應(yīng)用于,還可以應(yīng)用于其他任何框架中。有以下職責(zé)維持應(yīng)用的提供方法獲取提供方法更新通過(guò)注冊(cè)監(jiān)聽(tīng)器通過(guò)返回的函數(shù)注銷(xiāo)監(jiān)聽(tīng)器。同時(shí),的返回值實(shí)際上是一個(gè)函數(shù)可以解除監(jiān)聽(tīng)。 Redux是一個(gè)程序架構(gòu),源于Flux(Facebook提出的一種架構(gòu)),然而,它不僅可以應(yīng)用于React,還可以應(yīng)用于其他任何框架中。值得一提的是,Redux的源代碼很...
摘要:利用中間件實(shí)現(xiàn)異步請(qǐng)求,實(shí)現(xiàn)兩個(gè)用戶(hù)角色實(shí)時(shí)通信。目前還未深入了解的一些概念。往后會(huì)寫(xiě)更多的前后臺(tái)聯(lián)通的項(xiàng)目。刪除分組會(huì)連同組內(nèi)的所有圖片一起刪除。算是對(duì)自己上次用寫(xiě)后臺(tái)的一個(gè)強(qiáng)化,項(xiàng)目文章在這里。后來(lái)一直沒(méi)動(dòng),前些日子才把后續(xù)的完善。 歡迎訪(fǎng)問(wèn)我的個(gè)人網(wǎng)站:http://www.neroht.com/? 剛學(xué)vue和react時(shí),利用業(yè)余時(shí)間寫(xiě)的關(guān)于這兩個(gè)框架的訓(xùn)練,都相對(duì)簡(jiǎn)單,有的...
摘要:為目前使用范圍最廣的網(wǎng)絡(luò)保護(hù)協(xié)議。身處攻擊目標(biāo)周邊的惡意人士能夠利用密鑰重裝攻擊,利用此類(lèi)安全漏洞。本文和大家一起探討下如何在三年內(nèi)快速成長(zhǎng)為一名技術(shù)專(zhuān)家。 業(yè)界動(dòng)態(tài) Vue 2.5 released Vue 2.5 正式發(fā)布,作者對(duì)于該版本的優(yōu)化總結(jié):更好的TypeScript 集成,更好的錯(cuò)誤處理,更好的單文件功能組件支持以及更好的與環(huán)境無(wú)關(guān)的SSR WiFi爆驚天漏洞!KRACK...
摘要:展示組件與容器組件的綁定庫(kù)的基本開(kāi)發(fā)思想是展示組件與容器組件相分離。技術(shù)上講,容器組件就是使用從樹(shù)中讀取部分?jǐn)?shù)據(jù),并通過(guò)來(lái)把這些數(shù)據(jù)提供給要渲染的組件。 說(shuō)明:閱讀本篇文章需要對(duì)Redux有一定的了解,對(duì)Redux不了解的同學(xué)可先看看這篇文章Redux技術(shù)架構(gòu)簡(jiǎn)介(一) 1. React中引入react-redux 為了讓Redux和React更好的配合,F(xiàn)acebook專(zhuān)門(mén)開(kāi)發(fā)了一個(gè)...
閱讀 2467·2021-11-15 11:36
閱讀 1215·2019-08-30 15:56
閱讀 2280·2019-08-30 15:53
閱讀 1070·2019-08-30 15:44
閱讀 685·2019-08-30 14:13
閱讀 1026·2019-08-30 10:58
閱讀 510·2019-08-29 15:35
閱讀 1332·2019-08-29 13:58