首先,一開始我們都知道redux跟react搭配的很好,redux扮演著資料倉儲的角色,但是許多的side effects卻需要開發者自行解決,例如:非同步執行,套用一個netflix發表Redux-Observable時(Netflix JavaScript Talks-RxJS + Redux + React = Amazing!)所提到的例子,當使用者點選一部影片,卻在影片載入完成前取消並點選了另一部影片時,這時除了剛剛已經發送的request外會在發送一條新的request,然而當前一個發送的request返還時,我們已經不需要那個request,所以必須對前一個request做出判斷,是不是取消點選,是的話則不採用...等等的判斷,這時Redux-Observable就非常適合運用在這種專案的處理上。
當然也有較容易使用的React-thunk及Redux-Saga,但是因為實習關係,公司採用Redux-Observable,所以我也跟進學習Redux-Observable,一探Redux-Observable的強大!
(但是我的練習中不會有如此複雜的判斷,專案使用到的部分為發送request以及收到後對response的處理)
step1 - 安裝RxJs
npm install rxjs –save
RxJS 在JerryHong作者的文章裡面就有提到Observable的許多Operator可以做使用,當需要用到其方法時,引入即可。
以下為例:
import { of } from 'rxjs/observable/of';
import { from } from 'rxjs/observable/from';
import { merge } from 'rxjs/observable/merge';
import { empty } from 'rxjs/observable/empty';
import { mergeMap } from 'rxjs/operators/mergeMap';
step2 - 安裝redux-observable
npm install redux-observable –save
step3 - Epic函數
何謂Epic函數?
這邊引用Taiming作者的解釋來了解何謂Epic函數,並附上來源(網址)
根據官網的說明,Epics 是一個「 Actions in, actions out 」的函數,我們發送完action,在reducers接收到action之後,Epics函數才會監聽並接收到action。
簡單來說,action會在我們發送完之後,依序經過reducer以及Epics函數,而且因為Ecpis是action out,所以在Ecpis做完事情之後,可以再發送action回到reducer。
上述聽起來有些繞口,但多將這段話多念幾次再搭配上實作真的對Epic函數的理解有些許幫忙。
create發送請求的action
/* actions/index.js */
//發送 口罩資訊request
export const fetchMaskInformation = () => {
return {
type: 'FETCH_MASK_INFORMATION',
}
}
撰寫epic函數
/* epics/index.js */
import { empty } from 'rxjs';
import { ajax } from 'rxjs/ajax';
// 引入combineEpics方法
import { combineEpics } from 'redux-observable';
import { mergeMap, catchError } from 'rxjs/operators';
const maskGetList = (action$) =>
action$.ofType('FETCH_MASK_INFORMATION').pipe(
mergeMap(action => {
return ajax.getJSON(`網址`).pipe(
mergeMap(response => {
console.log('res:',response);
return empty();
})
)
})
);
// combineEpics會將參數中的epic函數合併在一起
export default combineEpics(maskGetList);
step4 - 撰寫configureStore
/* configureStore.js */
// import負責創建store的函式createStore
import { createStore, applyMiddleware } from 'redux';
// 引入createEpicMiddleware
import { createEpicMiddleware } from 'redux-observable';
import Reducer from './reducers/index';
import Epic from './epics/index';
export default function configureStore() {
// createEpicMiddlewarec會將epic函數轉為redux中間件
const epicMiddleware = createEpicMiddleware();
// https://github.com/zalmoxisus/redux-devtools-extension
// 將reducer傳入以創建一個store
const store = createStore(
Reducer,
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__(applyMiddleware(epicMiddleware)),
);
epicMiddleware.run(Epic);
return store;
}
step5 - 在App.js引入configureStore
/* App.js */
import configureStore from './configureStore';
// Provider是react-redux中的組件,它會接收上方在Redux中創建的store,並根據和component綁在一起的需求單mapStateToProps上要求的資料從store中取出,再透過props流向component。
import { Provider } from 'react-redux';
const store = configureStore();
// 將store傳給送個每個component
<Provider store={store}>
<div>
Hello World!
</div>
</Provider>
這樣就可以順利取得口罩的資訊囉!
如下圖:
下篇文章會紀錄將所取得的口罩資訊呈現到畫面上的過程~
先呈上 上禮拜刻了許久的口罩頁面
過程中花了許多時間在熟悉Google Map Api的部分,也打算來寫篇React使用Google Map Api的紀錄XD
雖然沒有趕上第十關的截止時間,但我還是要繼續完成它 Fighting!!
介面設計:Penny Yang(網址)
是來在THE F2E活動中Penny Yang設計師所提供的設計稿來刻板的
我也是前端的小菜鳥,所以要是有什麼寫得不好的地方,大師路過還請多給我一些指點,也請各位大師鞭小力點XD
如果你/妳已經是在前端上有一兩年經驗的,因本系列文章偏向前端入門,可能本系列文章不太適合你/妳,但也歡迎你/妳給予一些建議。
在複習 Redux-Observable 的時候找一些文章來看,沒想到看到一半居然看到自己的名字 XD
希望我沒有荼毒到大家,哈哈哈