redux-thunkの導入とタスク追加処理の修正 (STEP 1 : 誰でも読み込み・書き込みできるタスク管理アプリを作る - React + Redux + Firebase チュートリアル)

★前回の記事

yucatio.hatenablog.com

state更新のタイミング

Firebaseへの更新の際に、以下の3つのタイミングでstateを更新したいと思います。

  • Firebaseへの投稿直前
  • Firebaseへの通信が成功した時
  • Firebaseへの通信が失敗した時

Reduxでは、通常1回のdispatchで1つのactionしか発行することができませんが、redux-thunkを使うことで、(主にコンポーネント側からの)1回のdispatchで何回ものactionをdispatchをすることができます。また、firebaseからの応答が返ってきてからdispatchしたいという要望にも応えてくれます。

redux-thunkをインストールします。

$ yarn add redux-thunk

redux-thunkをreduxに組み込む

コーディングをしていきます。

始めに、redux-thunkをmiddlewareとして組み込みます。

src/index.js

import { createStore, applyMiddleware, compose } from 'redux'  // #1
import thunk from 'redux-thunk' // #1
import { reactReduxFirebase, getFirebase } from 'react-redux-firebase' // #1
// 他のimportは変更なし

// 中略

const createStoreWithFirebase = compose(
  applyMiddleware(thunk.withExtraArgument({getFirebase})),  // #2
  reactReduxFirebase(firebase, {})
)(createStore);

// 後略
  • reduxからapplyMiddleware、redux-thunkからthunk, react-redux-firebaseからgetFirebaseのimportを追加します。
  • composeの引数にapplyMiddlewareを追加し、dispathの際ににthunkを使用するよう指定します。firebaseをredux-thunkからも使えるように、getFirebaseを追加の引数として渡しています。

actionの実装

次に、addTodo actionを変更します。

src/actions/index.js

export const addTodo = text => {
  return (dispatch, getState, {getFirebase}) => {  // #1
    dispatch({ type: 'ADD_TODO_REQUEST' }); // #2
    const firebase = getFirebase();
    firebase.push('todos', {completed: false, text})  // #3
    .then(() => {
      dispatch({ type: 'ADD_TODO_SUCCESS' });  // #4
    }).catch(err => {
      dispatch({ type: 'ADD_TODO_ERROR' , err});  // #5
    });
  }
}

// let nextTodoId = 0 は削除する  // #6

元のaddTodoとは全然違う雰囲気になってしまいました。

  • redux-thunkを使用するので、オブジェクトを返すのではなく、関数を返すように変更します(#1)。
  • 始めに、ADD_TODO_REQUEST actionをdispatchして送信中の旨を画面に表示する用意をします(#2)。対応するreducerは次回で作成します。(ADD_TODO_SUCCESS, ADD_TODO_ERRORも同様)
  • Firebaseにデータをpushします(#3)。todosというパスに{completed: false, text}というデータを新規登録しています
  • データのpushが終わったら(サーバにデータが登録されたら)、ADD_TODO_SUCCESS actionをdispatchします(#4)。
  • 途中でエラーがあれば、ADD_TODO_ERROR actionをdispatchします(#5)。
  • nextTodoIdはもう使用しないので削除します(#6)。

#3でデータが送信されると、Firebaseからreact-redux-firebaseに通知がされ、state(state.firebase.data.todos)を書き換えます。そしてタスク一覧が自動で再描画されます。タスクを一覧に追加する処理を実装する必要がないので、楽に実装することができました。

動作確認

ブラウザで確認しましょう。

f:id:yucatio:20180927144436p:plain

よい感じですね。

念のためFirebaseにデータが登録されているかどうか見て見ましょう。

f:id:yucatio:20180927144823p:plain

登録されていました。

以上でタスク追加処理の実装は終わりです。

★次回の記事

yucatio.hatenablog.com

★目次

yucatio.hatenablog.com