reactのredux関連の副作用を扱うケースが発生したのでその時のメモです。
redux-sagaとは?
公式ホームページから引用すると 直感的な副作用を管理ツール
だそうです。
https://redux-saga.js.org/
具体的には、react内の処理の
- 非同期実行
- 並列実行
を簡易的に実装できるようにするツールです。
ジェネレーター
redux-sagaはジェネレーターという機能を軸としているので、先にこちらを解説します。
端的にいうと、ある関数をカスタマイズして、処理を途中で止めてその時点での値を返したり、止めた処理から再開させたりします。
簡単に言うとコルーチンです。
function* generater() {
yield 1;
yield 2;
yield 3;
return 4;
}
const iterater = generater();
console.log(iterater.next()) //{"value": 1,"done": false}
console.log(iterater.next()) //{"value": 2,"done": false}
console.log(iterater.next()) //{"value": 3,"done": false}
console.log(iterater.next()) //{"value": 4,"done": end}
function*
でジェネレーターの関数を宣言します。そして、yieldで処理を止める場所とその時点で返す値を指定します。
そして完全に処理を止めるときはreturnで値を返します。
そして、ジェネレーター関数を呼ぶことでイテレーターを返します。
そして、next関数を呼ぶことで、yieldの時点で処理を止め、値を返します。再度next関数を実行すると止まった処理の直後から再度実行されます。
redux-saga effect creator
話を戻すと、redux-sagaは副作用を管理するために、effect creator という概念があります。
dispatchや同期処理などを行うための小さな処理の単位だと思ってください。
以下はよく使うやつです。
call
処理を同期的に実行する関数です。この関数の引数には通常の関数かジェネレーター関数を渡せます。
put
actionを引数に渡してactionをdispatchします。
selector
selectorを渡してstoreからデータをもらってきます。
takeEvery
actionがdispatchされた時に実行されます。
サンプルコード
公式ホームページから引っ張ってきたコードを見ます。
import { call, put, takeEvery, takeLatest } from 'redux-saga/effects'
import Api from '...'
// Worker saga will be fired on USER_FETCH_REQUESTED actions
function* fetchUser(action) {
try {
const user = yield call(Api.fetchUser, action.payload.userId);
yield put({type: "USER_FETCH_SUCCEEDED", user: user});
} catch (e) {
yield put({type: "USER_FETCH_FAILED", message: e.message});
}
}
// Starts fetchUser on each dispatched USER_FETCH_REQUESTED action
// Allows concurrent fetches of user
function* mySaga() {
yield takeEvery("USER_FETCH_REQUESTED", fetchUser);
}
見ての通り、redux-sagaのeffectは全てyiledをつけます。これはお約束として考えときましょう。
最後に
今回は大雑把に概要把握レベルでのメモです。
effectやeffect creater の処理などは別個にまとめていきたいとおもいます。