使用 Saga 輔助函式
redux-saga
提供一些輔助函式來包裝內部函式,以在將某些特定 Action 傳送至應用程式商店時建立工作。
這些輔助函式建立在較低層級的 API 之上。在進階部分中,我們將看到如何實作這些函式。
第一個函式 takeEvery
最為人所熟知,且提供與 redux-thunk
相似的行為。
我們以常見的 AJAX 範例來說明。在每次按一下擷取按鈕時,我們會傳送一個 FETCH_REQUESTED
Action。我們希望透過啟動一個從伺服器擷取一些資料的工作來處理此 Action。
首先,我們建立將執行非同步 Action 的工作
import { call, put } from 'redux-saga/effects'
import Api from './path/to/api'
export function* fetchData(action) {
try {
const data = yield call(Api.fetchUser, action.payload.url)
yield put({ type: 'FETCH_SUCCEEDED', data })
} catch (error) {
yield put({ type: 'FETCH_FAILED', error })
}
}
要在每個 FETCH_REQUESTED
Action 中啟動以上工作
import { takeEvery } from 'redux-saga/effects'
function* watchFetchData() {
yield takeEvery('FETCH_REQUESTED', fetchData)
}
在上述範例中,takeEvery
允許多個 fetchData
案例同時啟動。在特定時刻,我們可以在一個或多個先前的 fetchData
作業尚未終止時啟動新的 fetchData
作業。
如果我們只想要取得最新發出的請求回應(例如要持續顯示資料的最新版本),我們可以使用 takeLatest
輔助程式
import { takeLatest } from 'redux-saga/effects'
function* watchFetchData() {
yield takeLatest('FETCH_REQUESTED', fetchData)
}
與 takeEvery
不同,takeLatest
任一時間點只允許一個 fetchData
作業執行。而且會是最晚啟動的作業。如果先前作業在另一個 fetchData
開始時仍在執行,先前作業會自動取消。
如果您有多個 Sagas 觀看不同的動作,您可以使用那些建置中輔助程式建立多個監控程式,其行為就像是在使用 fork
衍生它們(我們稍後會討論 fork
。就目前而言,把它視為一種讓我們可以在背景中啟動多個 Sagas 的效果)。
例如
import { takeEvery } from 'redux-saga/effects'
// FETCH_USERS
function* fetchUsers(action) { ... }
// CREATE_USER
function* createUser(action) { ... }
// use them in parallel
export default function* rootSaga() {
yield takeEvery('FETCH_USERS', fetchUsers)
yield takeEvery('CREATE_USER', createUser)
}