森です。redux アプリで redux-saga を使って定期実行処理を書いてみました。
要件
redux-saga で以下を実装する方法を検討しました。
- 定期的にステート(本稿では reducer で分割したストア)の値をチェックして何かする
- 定期的に API コールを行い、ストアを更新する
- アプリが起動している間ずっとではなく、開始条件と終了条件をつけたい。
- 終了条件は複数ある
答案
定期的にストアの値をチェックして何かするの実装例を書いてゆきます。redux-saga の公式ドキュメントの cancel の説明が参考になります。これをみつけられるかがキモかと思います。
ActionTypes
_TRIGGER、_STOP、_EXEC、_END の4種類を一組として、CHECK_ ではじめるルールとしました。
- ActionTypes.CHECK_SAMPLE_TRIGGER
- ActionTypes.CHECK_SAMPLE_STOP
- ActionTypes.CHECK_SAMPLE_EXEC
- ActionTypes.CHECK_SAMPLE_END
以下の2つは redux-saga で実行するアクションのアクションのタイプです。
- ActionTypes.CHECK_SAMPLE_EXEC //=> これがビジネスロジックの開始合図
- ActionTypes.CHECK_SAMPLE_END
以下の2つは redux-saga 以外で実行するアクションのタイプです。
- ActionTypes.CHECK_SAMPLE_TRIGGER //=> saga への定期実行開始依頼
- ActionTypes.CHECK_SAMPLE_STOP //=> saga への定期実行終了依頼
アクション
アクションの例です。
特徴はありません。
リデューサー
リデューサーは必要ないので作りません。
saga
単純な redux-saga の例です。ActionTypes.CHECK_SAMPLE_STOP と ActionTypes.LOGOUT_OK の2つのアクションを終了条件としました。
ミドルウェア
私たちのプロジェクトでは、ビジネスロジックはミドルウェアに書いています。以下は単純なミドルウェアの例です。
▼ src/middleware/periodic_inspections/sample.js
ミドルウェアでは次のようにステートを取り出せます。
const stateName = store.getState().stateName;
テスト
redux-saga の基本的なテストの例です。
「定期的に API コールを行いストアを更新する」処理も似たようなものです。