redux-saga
参考資料
- https://redux-saga.js.org/docs/introduction/BeginnerTutorial
- https://qiita.com/macotok/items/ec5460ac17f5a20c4735
- https://fintan.jp/?p=3064
- https://tech.stmn.co.jp/entry/2020/05/14/143012
特徴
- 非同期処理をシンプルにする
- 読みやすく、書きやすく、テストしやすい
- generator のおかげ
- Composition の思想を持つ?
- 複数のタスクを、並行実行したり、レース実行したり、キャンセルしたりできる。
メリット
- 複雑化しにくい(ほんとか)
- redux-thunk は Action Creater に処理を記述する一方で、
- redux-saga は saga コンポーネントに記述できるから
- テストが書きやすい
- Async/Await などの非同期処理のネストが深くならずに済む
Effect
用語
- Effect
- プレーンなオブジェクト
- generator で作成される
- middleware で解釈される
- Effect creators
- Effect を生成する役割を持つ関数
- generator の中で使用する
Effect creators の一覧
- take, takeEvery, takeLatest
- 処理をスタートするための action を拾うために使う
watchDeleteUserRequest
的な generator の中に記載する- 引数に実際に実行したい generator を渡す
- 3つの違い
- take --- 同じアクションが複数回来たときは逐次処理する?自信なし
- takeEvery --- 同じアクションが複数回来たときは並行処理する。迷ったらこれか?
- takeLatest --- 同じアクションが複数回来たときは古い処理をキャンセルして最新のもののみ処理する。
- call
- Promise 等を引数に取る
- Promise 等の完了を待つ
- 引数には API リクエストを行う関数+引数を与える。
- 同期的
- 非同期的に使いたい場合は fork を使え
- put
- redux の dispatch と同じ
- select
- store の値をとってこれる(用法・用量を守らないと大変なことになりそうな予感)
基本的なコード
以下の例では、Wather saga は、INCREMENT_ASYNC
を受け取るごとに、incrementAsync
タスクを spawn (並行実行)する。
// Worker sagaという
export function* incrementAsync() {
yield somePromiseToDelay(1000);
yield put({ type: 'INCREMENT' });
}
// Watcher sagaという。最終的にこれをmiddlewareに渡す。
export function* watchIncrementAsync() {
yield takeEvery('INCREMENT_ASYNC', incrementAsync);
}
並行実行
並行で複数の非同期処理を走らせるには all を使う。以下の場合に処理が次に進む。
- すべて resolve される
- いずれかが reject される
yield all([call(fetchData1, text1), call(fetchData2, text2)]);