Redux Thunkで非同期通信

どうも、ぽっぽです。

GitHub – microsoft\frontend-bootcamp: Frontend Workshop from HTML\CSS\JS to TypeScript\React\Reduxを参考にRedux Thunkについて理解したことを紹介します。

基本的なRedux storeは同期的に更新します。Reduxでajaxなどによって非同期通信をするときはstoreをミドルウェアで拡張したthunkを利用します。

Redux Thunkミドルウェアはactionの代わりに関数を返すaction createrを使います。thunkはactionをdispatchするのを遅らせたり、ある条件のときだけdispatchするものです。返される内部の関数はdispatchgetStateを引数に持ちます。

Thunkとは何か

thunkとは式をラップしてその評価を遅らせる関数です。xは評価された3が代入されます。fooは評価されずに関数が代入されます。foo()と呼び出して始めて評価されます。

let x = 1 + 2;
let foo = () =>  1 + 2 ;
console.log('x is ' ,x,' foo is ',foo,' foo() is ', foo()); //x is  3  foo is  () => 1 + 2  foo() is  3

thunkを使ったAction creator

action creatorは単にオブジェクトを返す関数です。

function addTodo(label: string) {
  return { type: 'addTodo', id: uuid(), label };
}

サービスを呼ぶためのaction creatorは下記のようになります。

function addTodo(label: string) {
  return async (dispatch: any, getState: () => Store) => {
    const addAction = actions.addTodo(label);
    const id = addAction.id;
    dispatch(addAction);
    await service.add(id, getState().todos[id]);
  };
}
  1. 返される関数は引数にdispatchgetStateを引数に指定します。
  2. 内部関数はasyncを有効にします。awaitで非同期通信を実装します。
  3. 内部関数はstoreからのdispatch関数を通して追加のactionをdispatchする事ができます。
  4. 内部関数はまたgetStateによってstate treeにアクセスする事ができます。

具体的にaddTodo()を実行する場合はこのようになります。

let foo = addTodo('foo'); // 関数を代入
foo(dispatch, getState);  //内部関数を実行

プログラマーが実際に実装するのは、addTodo()を実行するまでで、それ以降はthunkが処理します。
これにより、thunkミドルウェアにdispatchするタイミングを丸投げするような格好になります。

Redux ThunkでTodoアプリを書いたソース

Reactで作成したTodoアプリにRedux Thunkを使ったソースをこちらからダウンロード出来ます。

このソースはCreate React App · Set up a modern web app by running one command.を使っています。複数のツールを組み合わせて必要な設定なども行ってくれているので便利でした。

npm install
npm start

Todoアプリを動作させる場合、NodeJSのコマンドプロンプトを開いて、ソースをダウンロードして展開した場所(package.jsonファイルがある)に移動します。1行目のコマンドを実行します。package.jsonのパッケージをインストールして、インストールが終わるまで数十秒ほど待ちます。
2行目のコマンドを実行するとブラウザにTodoアプリが表示されます。

終わるときは、コマンドプロンプト上でCtrl + Cをタイプします。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

先頭に戻る