iT邦幫忙

0

[筆記] React 如何使用 Redux-Observable:副線打怪一下(2)

  • 分享至 

  • xImage
  •  

為何要使用Redux-Observable?

首先,一開始我們都知道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的強大!
(但是我的練習中不會有如此複雜的判斷/images/emoticon/emoticon25.gif,專案使用到的部分為發送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>

這樣就可以順利取得口罩的資訊囉!
如下圖:
https://ithelp.ithome.com.tw/upload/images/20200225/20123842IhFaWaDRgs.png

下回預告

下篇文章會紀錄將所取得的口罩資訊呈現到畫面上的過程~

先呈上 上禮拜刻了許久的口罩頁面/images/emoticon/emoticon13.gif
過程中花了許多時間在熟悉Google Map Api的部分,也打算來寫篇React使用Google Map Api的紀錄XD
雖然沒有趕上第十關的截止時間,但我還是要繼續完成它 Fighting!!
https://ithelp.ithome.com.tw/upload/images/20200225/20123842rl6AWLFgYd.png
https://ithelp.ithome.com.tw/upload/images/20200225/20123842jbOU4BLEjT.jpg
介面設計:Penny Yang(網址)
是來在THE F2E活動中Penny Yang設計師所提供的設計稿來刻板的

問題與討論

我也是前端的小菜鳥,所以要是有什麼寫得不好的地方,大師路過還請多給我一些指點,也請各位大師鞭小力點XD
如果你/妳已經是在前端上有一兩年經驗的,因本系列文章偏向前端入門,可能本系列文章不太適合你/妳,但也歡迎你/妳給予一些建議。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Taiming
iT邦研究生 5 級 ‧ 2020-09-24 08:03:37

在複習 Redux-Observable 的時候找一些文章來看,沒想到看到一半居然看到自己的名字 XD
希望我沒有荼毒到大家,哈哈哈

我要留言

立即登入留言