摘要:基本流程創(chuàng)建帶有三個(gè)方法發(fā)出處理數(shù)據(jù)每次后的數(shù)據(jù)即得到的數(shù)據(jù)即一個(gè)新的所以是一個(gè)對(duì)象每次都是上次返回的值所以用即返回的新?tīng)顟B(tài)新的即本次的返回值所以每次都是往空的對(duì)象里先推再新增屬性或改變?cè)瓉?lái)屬性的值層通過(guò)方法設(shè)置監(jiān)聽(tīng)函數(shù)一旦發(fā)生變化就會(huì)
基本流程
1.創(chuàng)建store,帶有三個(gè)方法:store.dispatch,store.subscribe,store.getState
import { applyMiddleware ,createStore } from "redux"; const store = createStore( reducer, applyMiddleware(thunk, logger) );
2.view發(fā)出dispatch->action
del = () => { store.dispatch({ type: "DEL", data: this.state.count - 1 }); }
3.reducer處理action數(shù)據(jù)
每次dispatch后return的數(shù)據(jù)即store.getState()得到的數(shù)據(jù),即一個(gè)新的state.
所以state是一個(gè)對(duì)象,每次都是上次返回的值.
所以用Object.assign({}, state, {count: action.data})
export default (state = {}, action) => { switch (action.type) { // state即返回的新?tīng)顟B(tài),新的state即本次的返回值,所以每次都是往空的對(duì)象里,先推state,再新增屬性或改變?cè)瓉?lái)屬性的值 case "ADD": return Object.assign({}, state, {count: action.data}); case "ADD2": return Object.assign({}, state, {count: action.data}); case "ADD3": return Object.assign({}, state, {count: action.data}); case "DEL": return Object.assign({}, state, {count: action.data}); case "AJAX": return Object.assign({}, state, {res: action.data.res}); default: return { count: 0, res: "aaaa" }; } }
4.view層通過(guò)store.subscribe()方法設(shè)置監(jiān)聽(tīng)函數(shù),一旦state發(fā)生變化,就會(huì)自定執(zhí)行這個(gè)函數(shù).
在這個(gè)函數(shù)里setState,就會(huì)觸發(fā)整個(gè)組件的render.
store.subscribe(() => { // subscribe即,每一次dispatch,都會(huì)觸發(fā)reducer處理數(shù)據(jù),即觸發(fā)store.subscribe this.setState({ count: store.getState().count, // reducer返回新的state,即state的值被改變state = 1 res: store.getState().res }); });異步操作
1.用戶發(fā)出Action,Reducer函數(shù)算出新的State,View重新渲染.
2.異步操作怎么辦? Action發(fā)出以后,Reducer立即算出State,這叫做同步;Action發(fā)出以后,過(guò)一段時(shí)間再執(zhí)行Reducer,這就是異步.
怎樣才能Reducer在異步操作結(jié)束后自動(dòng)執(zhí)行呢?這就要用到新的工具:中國(guó)件(middleware)
3.中間件
只有發(fā)送Action的這個(gè)步驟,即store.dispatch()方法,可以添加功能.
可以對(duì)store.dispatch進(jìn)行如下改造.
let next = store.dispatch; store.dispatch = function dispatchAndLog(action) { console.log("dispatching", action); next(action); console.log("next state", store.getState()); }
上面代碼中,對(duì)store.dispatch進(jìn)行了重定義,在發(fā)送Action前后添加了打印功能,這就是中間件的雛形.
中間件就是一個(gè)函數(shù),對(duì)store.dispatch方法進(jìn)行了改造,在發(fā)出Action和執(zhí)行Reducer這兩步之間,添加了其他功能.
4.中間件的用法
redux-logger提供一個(gè)生成器createLogger,可以生成日志中間件logger,然后,將它放在applyMiddleware方法中,
傳入createStore方法,就完成了store.dispatch()的功能增強(qiáng).
import { applyMiddleware ,createStore } from "redux"; import { createLogger } from "redux-logger"; import thunk from "redux-thunk"; const logger = createLogger(); const store = createStore( reducer, applyMiddleware(thunk, logger) );
5.applyMiddleware
applyMiddleware是Redux的原生方法,作用是將所有中間件組成一個(gè)數(shù)組,依次執(zhí)行.
6.異步操作的基本思路
操作開(kāi)始時(shí),送出一個(gè)Action,觸發(fā)State更新為"正在操作"狀態(tài),重新渲染.
操作結(jié)束后,再送出一個(gè)Action,觸發(fā)State更新為"操作結(jié)束",view再一次重新渲染.
1.異步操作至少要送出兩個(gè)Action,用戶觸發(fā)第一個(gè)Action,這個(gè)跟同步操作一樣,沒(méi)有問(wèn)題.
如何才能在操作結(jié)束時(shí),系統(tǒng)自動(dòng)送出第二個(gè)Action呢?
add3 = () => { store.dispatch(dispatchAction(this.state.count + 3)); } function dispatchAction(count) { return (dispatch) => { dispatch({ type: "ADD3", data: count }); } }
dispatchAction是一個(gè)Action Creater,返回一個(gè)函數(shù),這個(gè)函數(shù)執(zhí)行后,發(fā)出一個(gè)action,然后執(zhí)行異步操作,拿到結(jié)果后,再次dispatch,發(fā)出一個(gè)Action.
dispatchAction返回了一個(gè)函數(shù),而普通的action creator默認(rèn)返回一個(gè)對(duì)象.
返回的函數(shù)的參數(shù)是dispatch和getState這兩個(gè)redux方法.
action是由store.dispatch方法發(fā)送的,而store.dispatch方法正常情況下,參數(shù)只能是對(duì)象,不能是函數(shù).
這時(shí),就使用redux-thunk中間件,改造dispatch,使得后者可以接受函數(shù)作為參數(shù).
1.首先,這是個(gè)關(guān)于action creator的解釋.
什么是action creator? 返回action的函數(shù).
為什么要用action creator?圖個(gè)方便吧.
function changeNum(count) { return { type: "ADD2", data: count } } add2 = () => { store.dispatch(changeNum(this.state.count + 2)); }
2.Thunk的做法就是擴(kuò)展了這個(gè)action creator.
Thunk允許action creator返回一個(gè)函數(shù),而且這個(gè)函數(shù)第一個(gè)參數(shù)是dispatch.
所以不光改造action creator,如果你要用thunk,你還要把它放進(jìn)middleware里去,這樣函數(shù)類(lèi)型的action就被thunk middleware捕獲,
根據(jù)你的函數(shù)邏輯,再去dispatch常規(guī)的action.
這樣Async Action其實(shí)就是發(fā)Ajax之前dispatch一發(fā),收到服務(wù)器響應(yīng)后dispatch一發(fā),
報(bào)錯(cuò)的話再來(lái)dispatch一發(fā).
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/84314.html
摘要:中間件對(duì)異步的實(shí)現(xiàn)非常重要,因?yàn)樵谥暗奈恼轮形覀冋劦?,是一個(gè)行為抽象,只是一個(gè)對(duì)象,是一個(gè)純函數(shù),不應(yīng)該有調(diào)用和副作用的操作。這個(gè)函數(shù)并不需要保持純凈,它還可以帶有副作用,包括執(zhí)行異步請(qǐng)求。那么如何在中進(jìn)行網(wǎng)絡(luò)請(qǐng)求標(biāo)準(zhǔn)的做法是使用。 在之前的淺談Flux架構(gòu)及Redux實(shí)踐一文中我們初步的談及了Redux的數(shù)據(jù)流思想,并做了一個(gè)簡(jiǎn)單的加減器。但是還沒(méi)有接觸到Redux更多常用的場(chǎng)景,...
摘要:在函數(shù)式編程中,異步操作修改全局變量等與函數(shù)外部環(huán)境發(fā)生的交互叫做副作用通常認(rèn)為這些操作是邪惡骯臟的,并且也是導(dǎo)致的源頭。 注:這篇是17年1月的文章,搬運(yùn)自本人 blog... https://github.com/BuptStEve/... 零、前言 在上一篇中介紹了 Redux 的各項(xiàng)基礎(chǔ) api。接著一步一步地介紹如何與 React 進(jìn)行結(jié)合,并從引入過(guò)程中遇到的各個(gè)痛點(diǎn)引出 ...
摘要:我們可以為元素添加屬性然后在回調(diào)函數(shù)中接受該元素在樹(shù)中的句柄,該值會(huì)作為回調(diào)函數(shù)的第一個(gè)參數(shù)返回。使用最常見(jiàn)的用法就是傳入一個(gè)對(duì)象。單向數(shù)據(jù)流,比較有序,有便于管理,它隨著視圖庫(kù)的開(kāi)發(fā)而被概念化。 面試中問(wèn)框架,經(jīng)常會(huì)問(wèn)到一些原理性的東西,明明一直在用,也知道怎么用, 但面試時(shí)卻答不上來(lái),也是挺尷尬的,就干脆把react相關(guān)的問(wèn)題查了下資料,再按自己的理解整理了下這些答案。 reac...
摘要:舉例來(lái)說(shuō)一個(gè)異步的請(qǐng)求場(chǎng)景,可以如下實(shí)現(xiàn)任何異步的邏輯都可以,如等等也可以使用的和。實(shí)際上在中,一個(gè)就是一個(gè)函數(shù)。 書(shū)籍完整目錄 3.4 redux 異步 showImg(https://segmentfault.com/img/bVyou8); 在大多數(shù)的前端業(yè)務(wù)場(chǎng)景中,需要和后端產(chǎn)生異步交互,在本節(jié)中,將詳細(xì)講解 redux 中的異步方案以及一些異步第三方組件,內(nèi)容有: redu...
摘要:一種通知請(qǐng)求成功的。對(duì)于這種,可能會(huì)把接收到的新數(shù)據(jù)合并到中,并重置。另外,有些會(huì)保存這些失敗信息,并在里顯示出來(lái)。 一、redux基礎(chǔ) redux 通過(guò) dispatch(action) -> 中間件 -> reducer處理數(shù)據(jù) -> 改變store -> 使用subscribe()監(jiān)聽(tīng)store改變更新視圖 的方式管理狀態(tài) 將所有狀態(tài)存儲(chǔ)在一個(gè)store對(duì)象里面 reducer...
閱讀 1343·2021-09-01 11:40
閱讀 3957·2021-08-05 10:03
閱讀 984·2019-08-30 15:54
閱讀 2826·2019-08-29 12:53
閱讀 3191·2019-08-29 12:23
閱讀 947·2019-08-26 13:45
閱讀 2288·2019-08-26 10:41
閱讀 2543·2019-08-23 16:44