跳至主要內容

使用 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)
}