Help us understand the problem. What is going on with this article?

ReduxでAPIの通信の状態を共通で扱うTips(feat. typescript-fsa)

More than 1 year has passed since last update.

APIコールが発生する処理を行った時にローディング中かどうかを示す loading なり fetching なりのフラグを用意すること、結構あると思います。これを様々なActionごとに逐一準備するのだるいのでまとめて用意する方法と、それをtypescript-fsa使うと意識すること一つ減るよという小ネタです。

考え方はこちらのブログのアイデア完全にお借りしていて、typescript-fsa前提だとAction Typeが必ず特定のフォーマットになるので幸せになったという話。
https://medium.com/stashaway-engineering/react-redux-tips-better-way-to-handle-loading-flags-in-your-reducers-afda42a804c6

typescript-fsaの非同期アクション

typescript-fsaでは非同期なAction用に便利ActionCreatorCreatorを用意してくれており、それがactionCreator.asyncです。

export const fetchSomethingActions = actionCreator.async<
  { fuga: string }, // parameter type
  { hoge: string }, // success type
  { code: number } // error type
>('FETCH_SOMETHING');

こうすると下記のような関数を実行できて、特定のフォーマットのAction Typeを持ったActionを発行してくれる。

// リクエスト実行時に呼び出す
// Action Typeは FETCH_SOMETHING_STARTED になる
dispatch(fetchSomethingActions.started({ params: { fuga: 'hoge' } }));

// リクエスト成功時に呼び出す
// Action Typeは FETCH_SOMETHING_DONE になる
dispatch(fetchSomethingActions.done({ params: { fuga: 'hoge' }, result: { hoge: 'fuga' } }));

// リクエスト失敗時に呼び出す
// Action Typeは FETCH_SOMETHING_FAILED になる
dispatch(fetchSomethingActions.failed({ params: { fuga: 'hoge' }, error: { code: 1 } }));

詳しくはREADMEで。
https://github.com/aikoven/typescript-fsa

APIの通信の状態専用のreducerを用意する

こんな感じのreducerを用意します。

export const loadingReducer = (state = {}, action: { type: string }) => {
  const { type } = action;
  const matches = /(.*)_(STARTED|DONE|FAILED)/.exec(type);

  if (!matches) {
    return state;
  }

  const [, requestName, requestState] = matches;
  return {
    ...state,
    [requestName]: requestState === 'STARTED'
  };
};

正規表現で STARTED|DONE|FAILED いずれかが後ろに付いているかを判定しています。もしついている場合、STARTED の場合はまさにリクエストが走った時なのでtrueにします。成功か失敗した時はfalseにします。

あとはmapStateのとこでリクエスト名をキーに取ってくるだけ。

当たり前なんですがAction Typeのフォーマットを整えるのはtypescript-fsaの特権ではなく、普通に規約で縛ればいい話なんですが、typescript-fsaのようなActionCreatorCreatorがある前提なら意識しなくても守れるのが結構気分良かったです。

seya
最近の趣味はGraphQLとFigmaです。
https://note.mu/seyanote
linc-well
Linc'well(リンクウェル)は2018年創業のヘルスケアスタートアップです。我々は、医療のIT化を通じて、人々と社会の健康に貢献します。
https://www.linc-well.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away