redux-saga
redux-sagaは「タスク」という概念をReduxに持ち込む
タスクというのはプロセスのような独立した実行単位で、それぞれが別々に並行して動作する
redux-sagaはこのタスクの実行環境を提供します
それに加えて非同期処理をタスクとして記述するための道具立てである 「作用(Effects)」 と非同期処理を同期的に書き下す手段も提供してくれます
作用というのはタスクを記述するためのコマンド(命令、プリミティブ)のようなもので、例えば次のようなものがあります
select: Stateから必要なデータを取り出す
put: Actionをdispatchする
take: Actionを待つ、イベントの発生を待つ
call: Promiseの完了を待つ
fork: 別のタスクを開始する
join: 別のタスクの終了を待つ
Generator
redux-thunkと比較して良いこと
Action Creatorがシンプルになる
redux-thunkはAction Creatorが関数を投げる
必然的にAction Creatorに非同期処理のcodeや関連するlogicを詰め込むことになる
redux-sagaは非同期処理を記述する専用の仕組みであるタスクに書く
Action Creatorは本来の姿を取り戻して、Action objectを生成して返すだけになる
redux-thunkはmiddlewaresの一番外側に配置しないといけない
redux-thunkはdispatchされた関数を捕まえてひたすら実行する
code:js
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
普通のmiddlewareは関数を受け取れずにerrorになるので、まずredux-thunkが受け取って処理しないといけない
redux-loggerのようなmiddlewareでdebugしづらい
関数なので中身がどうなっているかは実行するかわからない
redux-sagaはplainなaction objectをdispatchする
順番を気にしない
loggingした時に中身がわかる、debugしやすい
API呼び出しのチェインがスムーズ
redux-thunkでは API.get('/path/a').then((...) => { API.get('/path/b').then((...) => {...}) }) のようにネストしてしまう
async/awaitでも書けるが、Action Creatorに処理を追記していくことになる
redux-sagaではもともとのAPI callを行うタスクに手を入れることなく書ける
そのタスクのなかでdispatchするactionを待つタスクを書けば良い
タスクは他のタスクで何をやっているかは気にしない
テストが書きやすい
redux-sagaではタスクのテストを書く
タスクはただのGenerator関数で、生成されたGeneratorがnext()で返すのはただのオブジェクト
つまりオブジェクトの値を比較するだけで済む
テストするべきはこのタスクが何をしようとしているかであって、その先で何をするかは知る必要がない
上述のAPI呼び出しチェインの場合では、API呼び出しが成功した後にもう一度別のAPIを呼び出すことをテストしないといけない
参考