redux-thunkとは?
actionCreatorで関数を返せるようになる。
非常にシンプルで、ActionCreater内部のロジックで非同期処理を実行できます。通常、ActionCreatorはピュアなオブジェクトを返さないといけないので非同期処理を書くのは不可能なのですが、redux-thunkを使えばそれが実現できます。
実際に、redux-thunkのreadmeのMotivationにも書かれていますが、「actioncreatorをアクション(オブジェクト)の代わりに関数を返す」ように実装できると書かれています。
actionCreatorで返す関数の引数にdispatchやgetStateを持たせることができる。
actionCreatorで関数を返せるようになりますが、その返す関数の引数としてdispatchやgetStateを持たせることができます。なので、actionCreator側でdispatchさせることが可能になります。
ただ、非常に自由度が高いのでうまく考えないとfatなアクションになってしまうので注意。
インストール
redux-thunkはreduxで非同期処理を実装するためのパッケージになります。
1 |
yarn add redux-thunk |
組み込み
reactであれば「src/index.js」などに下記のように記述します。
1 2 |
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; |
redux-thunkはミドルウェアになるのでミドルウェアを適用するためのreduxの関数であるapplyMiddlewareもimportする必要があります。createStoreメソッドの第二引数に指定します。
1 |
const store = createStore(reducer, applyMiddleware(thunk)) |
こうすることでReduxのStoreの中に非同期処理が組み込まれます。
actionsへの組み込み
非同期処理の場合は、dispatchの呼び出しを「コンポーネント側」ではなく「actionCreatorで返す関数側」で行なっているというわけですね。
1 2 3 4 5 6 7 8 9 10 |
import axios from 'axios' export const READ_EVENTS = 'READ_EVENTS' const ROOT_URL = 'https://xxx.com/api/v1' const QUERYSTRING = '?token=token123' export const readEvents = () => async dispatch => { const response = await axios.get(`${ROOT_URL}/events${QUERYSTRING}`) dispatch({ type: 'READ_EVENTS', response }) } |
なぜreduxでは「redux thunk」や、「redux saga」などのライブラリが必要なのか。
ReduxはAction Creatorによって生成されたアクションをStoreにディスパッチすることで単純な更新を行っているためです。そこで、Redux-thunkのようなミドルウェアを導入することでStoreの機能を拡張して、非同期ロジックを記述することが可能になります。
Redux Thunk
通常、Action CreatorはActionオブジェクトを返すが、Redux Thunkを使用すると「Thunk」という関数を返すようにできます。これによりActionのディスパッチを遅らせたり、特定の条件が満たされた場合のみディスパッチをするということができるようになります。
Action CreatorがThunkを返すことで、ReduxのReducer、Reactのコンポーネントに直接的な副作用を起こさないピュアな状態を保つことができます。(こうすることで、ReducerやReactコンポーネントのテスト、保守性、拡張性、再利用性などを高めることが可能になります。)
返す関数
返す関数の引数としてdispatchやgetStateを持たせることができるので、actionCreator側でディスパッチができるようになります。
Redux Thunkの欠点
Action Creator側に非同期な処理を記述することになるので、Action Creatorが肥大化しやすくなります。
Redux Saga
Redux ThunkのようにAction Creatorが肥大化してしまうようなアプリケーションではこちらを使うようにします。
この記事へのコメントはありません。