4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

redux-saga の API 通信時には Loader を表示させておきたい件

Last updated at Posted at 2019-08-23

やりたいこと

redux-saga の call を行う際に
レスポンスを待っている間はロード中をオーバーレイで表示をさせたい!

こういうやつ↓
003.gif

画像は material ui の circular
https://material-ui.com/components/progress/#circular

問題点

◇saga 全体を監視していずれかのタスクが call中 であるという判定を行いたい
◇しかし、既存の sagaのソースや fetch(axios)部分にまで侵入したくない
◇saga の記述をする際に、必要なコード量を増やしたくない

既存の記事等を検索するも、これらを満たしてくれる方法が見つからない・・・

解決策

海外サイトでも見当たらないので、公式ドキュメントを血眼になって読み漁ると
https://redux-saga.js.org/docs/api/
sagaMonitor なるものがあるらしい
説明を読んだが、sampleが記述されておらず、アホの僕には具体的な実装がよくわからない

ライブラリの中を見に行って、sagaMonitor を使用している場所を見つけた
https://github.com/redux-saga/redux-saga/blob/a79e2cda8530930c172d1ffb53027adb7443e879/examples/real-world/store/configureStore.prod.js

この @redux-saga/simple-saga-monitor というライブラリを見てみると
どうやら saga のロガーとして使用しているらしい
発火した effect や 解決した effect を検知できるようだ

という訳でこの sagaMonitor を使用して実装していく

sagaMonitor

何はともあれ、とりあえずコード

store.js
省略
.
.
.

import createSagaMiddleware from 'redux-saga'
import {setEffect, deleteEffect} from './actions/sagaMonitor'

import rootSaga from './sagas'

// 対象のコードはここから
const watchEffectEnd = (effectId, res) => {
  store.dispatch(deleteEffect(effectId))
};

const sagaMonitor = {
  effectRejected: (e) => {
    store.dispatch(deleteEffect(e.effectId))
  },
  effectTriggered: (event) => {
    if (event.effect.type === 'CALL') {
      store.dispatch(setEffect(event.effectId))
    }
  },
  effectResolved: watchEffectEnd,
}
// 対象のコードはここまで

export const history = createBrowserHistory()
const sagaMiddleware = createSagaMiddleware({sagaMonitor: sagaMonitor})

省略
.
.
.


let store = null;

export default function configureStore(preloadedState) {
  store = createStore(
    createRootReducer(history),
    preloadedState,
    bindMiddleware()
  );

  sagaMiddleware.run(rootSaga);

  return store;
}

そんなに解説するところは無いが

createSagaMiddleware()の引数に、作成したsagaMonitorオブジェクトを渡せばいいだけ
effectTriggered で、発火したタスク名やメソッド名がid付きで取得できる
effectResolved で、解決したタスク名等が発火時に付与されたid付きで取得できる

これで reducer に発火時にidを詰め、解決時にidを削除するという事が可能になる

あとはコンポーネント側で、reducer に何か詰まっている状態 の時はローダーを表示させれば良い

effectRejected とか他にもメソッドがあるけど、その辺はよしなにお願いします

最後に

sagaMonitor がこういう使い方しても良いのかはわかりません

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?