Redux-Saga
一個直覺的 Redux 副作用管理員。
容易管理、容易測試,且能有效地執行。
非同步
ES6 產生器讓非同步流程易於閱讀、撰寫以及測試。創造複雜的副作用而不用被細節弄得焦頭爛額。
專注於組成
Sagas 能夠以許多方法來處理並行的執行、任務並發、任務競速以及任務取消等問題。能完全掌控你的程式碼流程。
容易測試
在產生器的每一步或整體 saga 中斷言結果。無論如何,副作用測試都像測試應有的那樣,快速、簡潔且輕鬆。
範例用法
- 1. 發送一個行為
- 2. 開始一個副作用
- 3. 連線到儲存
- 4. 連線到儲存(新版本)
假設我們有個 UI,在按鈕被按下時從遠端伺服器抓取一些使用者資料。(為了簡潔,我們將只顯示觸發行為的程式碼。)
class UserComponent extends React.Component {...onSomeButtonClicked() {const { userId, dispatch } = this.propsdispatch({type: 'USER_FETCH_REQUESTED', payload: {userId}})}...}
此元件會送出一個純物件行為到儲存。我們將建立一個 Saga,觀察所有 USER_FETCH_REQUESTED
行為,並觸發一個 API 呼叫以抓取使用者資料。
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'import Api from '...'// Worker saga will be fired on USER_FETCH_REQUESTED actionsfunction* fetchUser(action) {try {const user = yield call(Api.fetchUser, action.payload.userId);yield put({type: "USER_FETCH_SUCCEEDED", user: user});} catch (e) {yield put({type: "USER_FETCH_FAILED", message: e.message});}}// Starts fetchUser on each dispatched USER_FETCH_REQUESTED action// Allows concurrent fetches of userfunction* mySaga() {yield takeEvery("USER_FETCH_REQUESTED", fetchUser);}
為執行我們的 Saga,我們必須使用 redux-saga
中介軟體將其連線到 Redux 儲存。
import { createStore, applyMiddleware } from 'redux'import createSagaMiddleware from 'redux-saga'import reducer from './reducers'import mySaga from './sagas'// Create the saga middlewareconst sagaMiddleware = createSagaMiddleware()// Mount it on the Storeconst store = createStore(reducer,applyMiddleware(sagaMiddleware))// Then run the sagasagaMiddleware.run(mySaga)// Render the application
這是新版的執行 saga,使用來自「 reduxjs/toolkit
」的「configureStore」取代來自「 Redux
」的「createStore」
import { configureStore } from '@reduxjs/toolkit'import createSagaMiddleware from 'redux-saga'import reducer from './reducers'import mySaga from './sagas'// Create the saga middlewareconst sagaMiddleware = createSagaMiddleware()const middleware = [sagaMiddleware]// Mount it on the Storeconst store = configureStore({reducer,middleware: (getDefaultMiddleware) =>getDefaultMiddleware().concat(middleware),})// Then run the sagasagaMiddleware.run(mySaga)// Render the application