跳至主要内容

使用 Saga 助手

redux-saga 提供了一些助手效果,它们包装了内部函数,以便在向 Store 派发某些特定动作时生成任务。

助手函数构建在更低级别的 API 之上。在高级部分,我们将看到如何实现这些函数。

第一个函数 takeEvery 是最熟悉的,它提供与 redux-thunk 相似的行为。

让我们用常见的 AJAX 示例来说明。每次点击“获取”按钮时,我们都会分派一个 FETCH_REQUESTED 动作。我们希望通过启动一个从服务器获取数据的任务来处理此动作。

首先,我们创建执行异步操作的任务

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 动作上启动上述任务

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 任务时,先前任务仍在运行,则先前任务将被自动取消。

如果您有多个 Saga 监听不同的动作,您可以使用这些内置辅助函数创建多个监听器,它们的行为就像使用 fork 来生成它们一样(我们将在后面讨论 fork。现在,将其视为一个允许我们在后台启动多个 Saga 的 Effect)。

例如

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