メインコンテンツにスキップ

Saga ヘルパーの使用

redux-saga は、Store に特定の action が発行されるとタスクを起動する内部関数をラップするヘルパーエフェクトを提供しています。

ヘルパー関数は、低レベル 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 インスタンスを開始できます。ある時点で、まだ終了していない 1 つ以上の前の fetchData タスクがある間に、新しい fetchData タスクを開始できます。

最新の発行されたリクエストの応答のみを取得したい場合(たとえば、データの最新バージョンを常に表示する場合)は、takeLatest ヘルパーを使用できます

import { takeLatest } from 'redux-saga/effects'

function* watchFetchData() {
yield takeLatest('FETCH_REQUESTED', fetchData)
}

takeEvery とは異なり、takeLatest ではいつでも 1 つの fetchData タスクしか実行できません。また、それは最新の開始タスクになります。別の fetchData タスクが開始されたときに、以前のタスクがまだ実行中の場合、以前のタスクは自動的にキャンセルされます。

異なるアクションを監視している Saga が複数ある場合は、これらの組み込みヘルパーを使用して複数のウォッチャーを作成できます。それらは、それらを起動するために使用される fork があるかのように動作します(後で fork について説明します。当面は、バックグラウンドで複数の saga を開始するエフェクトであると見なしてください)。

たとえば

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