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