歡迎指導與討論:)
前言
本文不涉及深入的知識,只是在概念層面和一個簡單的例子解釋redux-observable的工作原理。
redux-observable,是redux的一個中間件庫。它能夠自動響應我們所dispatch的actions並執行對應的函數,讓我們把復雜的異步函數分離到一些Epic的函數里面。因此不再需要react-thunk來讓redux支持所謂的異步action了,同時讓代碼耦合度降得更低。redux-observable讓redux的action更加純凈,都是干凈的對象字面量 —— redux-observable適合大型復雜的狀態管理,而且讓代碼分離度和可維護度更高。但可能需要先掌握RxJS的基本概念和api用法。
幾個概念
可觀察流與自動響應、redux的dispatch、Epics函數、redux-observable的內部原理。
可觀察流與自動響應
可觀察流相當於一個發射器,它能夠隨時間地流逝不斷 發送/產生 各種各樣的值,當我們監聽這個發射器時,就會收到發射過來的值並可以執行我們想要的操作。而啟動這個監聽,需要觸發 .subscribe( ) 。每當有一個新值發送時,subscribe里的代碼就會自動執行 —— 自動響應。
// 一個簡單的例子
發射器.subscribe( function( 收到的值 ){ // 根據值可以進行一些函數操作
})
redux的dispatch( action )
redux的dispatch(action)函數能夠根據action類型的不同,讓應用的狀態store響應它的變化。每當dispatch一個action時,應用狀態可能就會更變。
// 下面代碼觸發時,應用狀態會被刷新
dispatch({ type: 'man' })
Epics函數
redux-observable里的Epics函數主要作用是:1. 傳進一個action,然后return一個新的、不一樣的action。2. 這個Epics函數是一個發射器,因此我們能夠subscribe它,從而可以監聽並收到新的action。3. 每當我們調用redux的dispatch的時候,所有的Epics函數都會執行。
function (action$: Observable<Action>, store: Store): Observable<Action>;
redux-observable的內部原理
( 1 ) 每當我們使用redux的dispatch的時候,每個Epics函數都會收到我們所dispatch的action,然后Epics函數返回一個新的action。
(2)監聽Epics函數,將它返回的新的action,用來dispatch,從而更新應用狀態
// 用代碼表示就是
epic(actions$).subscribe( function( ){ dispatch( newAction ) // dispatch新的action
})
一個簡單的例子
// 定義兩個action creator // 1. 拉取某用戶數據 const fetchUser = username => ({ type: '拉取某用戶數據', target: username }); // 2. 拉取完成 const fetchUserDone = data => ({ type: '拉取完成', data}); // 定義一個Epics函數 const fetchEpics = action$ => action$.ofType('拉取某用戶數據') // 如果true則進行下一步否則退出 .mergeMap( action => // 提取action.target並進行ajax請求 ajax.getJson(`/api/users/${action.target}`) .map(function( data ){ fetchUserDone ( data )// 調用拉取完成函數,返回{ type: '拉取完成', data } }) );
從上面的這個例子我們看到:
(1)不再有異步action,即類型為函數的這種action,redux的action都是純凈的對象字面量了。
(2)拉取數據的函數寫到了Epics函數里面
(3)Epics函數會對action的類型進行判斷,滿足不了不會繼續執行
(4)注:上面的mergeMap、ajax、map這幾個都是RxJS的api。
總結
redux-observable的優點大概有這幾個,歡迎補充。(1)會自動響應redux的dispatch,每當觸發時都會執行我們定義的Epics函數。(2)把拉取數據等等的業務邏輯代碼可以分離到Epics函數里面,降低代碼耦合度,提升維護度(3)action都是純凈的對象字面量,不再需要引入redux-thunk。