1
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.

typescript-fsa-redux-thunkの紹介

Last updated at Posted at 2021-01-28

はじめに

redux-thunkをtypescriptで使っていた時に、typescript-fsa-rudx-thunkというパッケージが便利だったので紹介します。
非同期処理のactionを作るactionCreatorを提供しています。

typescript-fsaやredux-thunkの説明を詳しくすると長くなるので端折りながら。

typescript-fsaについて

Reduxの型定義をよしなにしてくれるパッケージはtypescript-fsaが有名。

import actionCreatorFactory from 'typescript-fsa';

const actionCreator = actionCreatorFactory();
//{foo: string}型がパラメータの型になる。
const somethingHappend = actionCreator<{foo: string}>('SOMETHING_HAPPENED');
console.log(somethigHappend({foo:"hoge"}));
// { type: 'SOMETHING_HAPPENED', payload: {foo:"hoge"})

payloadの型がactionCreatorのジェネリックスで指定した型になります。
型をactionCreatorを通して定義できます。

redux-thunkについて

redux-thunkはreduxで非同期処理を行う時に使用されるパッケージです。

redux-thunkを使わない場合

const somethingHappend = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

fetch("http://example.com")
  .then(response => response.text())
  .then(text => {
    store.dispatch(somthigHappend({foo:string});
  });

redux-thunkを使った場合

const somethingHappend = actionCreator<{foo: string}>('SOMETHING_HAPPENED');

const asyncSomethingHappend = () => (dispatch: any) => any{
  fetch("http://example.com")
    .then(response => response.text())
    .then(text => {
      dispatch(somthigHappend({foo:string});
    });
}
//asyncSomethingHappendはreduxのactionと同じようにdispatchできます。
store.dispatch(asyncSomethingHappend());

redux-thunkを使うと非同期処理を行う関数(thunkと呼ぶらしい)をdispatchできるようになりました。

非同期処理を行う関数(thunk)自体がactionとなるので、管理がしやすくなります。

typescript-fsa-redux-thunk

今までの説明では理解しやすくするために簡単な処理を書いていました。
しかし、私が実際に非同期処理をする時はいつも複雑になります。

通信が始まったときの処理だとか、終わったときの処理だとか、エラー時の処理だとか、
ただでさえ、reduxやredux-thunkを理解するのが大変なのに、、、

そこで、便利だったのがtypescript-fsa-redux-thunk。
非同期処理のaction(thunk)を作るactionCreaterを提供してくれています。

import actionCreatorFactory from 'typescript-fsa';
import { asyncFactory } from 'typescript-fsa-redux-thunk';

//ジェネリックスで渡しているStateはReduxのstoreのstateと同じ型です。
const createAsync = asyncFactory<State>(create);

interface LoginParams {
  email: string;
  password: string;
}

const login = createAsync<LoginParam,UserToken,CustomError>(
  'Login',
  // 引数で取っているparamsがLoginPramになります。
  async(params,dispatch) => {
    const res = await fetch("http://example.com/login",{
     method: 'POST',
     body: JSON.stringfy(params)
    })
    if(!res.ok) {
     throw new CustomError();
    }
    //UserToken型を返します。
    retrun res.json() as UserToken
  }
);
const loginParam:LoginParam = {email:'hoge@example.om',password:'fuga'}
store.dispatch(login(loginParam));
//login.asyncの中
//{
//  started: f LOGIN_STARTED
//  done: f LOGIN_DONE
//  failed: f LOGIN_FAILED
//  type: 'LOGIN'
//}

createAsyncは非同期処理のaction(thunk)を作るactionCreaterになります。

createAsyncで作られたthunkはdispatchされると、
started:非同期処理が始まったとき
done:非同期処理が完了したとき
faild:非同期処理が失敗したとき
上記の三つのactionがdispatchされる。
これらの三つのactionはlogin.asyncの中に定義されている。
いちいち自分で記述しなくてよいので、楽です。

createAsyncの三つのジェネリックは順番に
1.createAsyncが作ったthunkの引数の型・createAsync第二引数の関数の第一引数
2.createAsyncの第2引数の返り値・doneアクションのparameter
3.エラーの型
になっている。

一番うれしいのが、started・done・faildのアクションを定義してくれていること。

最後に

説明難しい。

1
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
1
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?