TIS ENGINEER NOTE

ITエンジニアのためのキャリア向上ノウハウブログ

プログラミング

React + Reduxでサーバー通信ってどこでやればいいの?

更新日:

React + Reduxはその柔軟性から、Googleで調べて出てくる情報の一貫性がなく、機能を実装するときの調査が結構大変。

今回はリアルタイムチャットツールを開発したときの経験を元にReact + Reduxでサーバー通信を行うときの書き方について紹介していきます。

ちなみに今回の例ではRuby on RailsでAPIを構築し、そちらへ通信を行うという構成です。

使用するライブラリなど

サーバー通信用のライブラリ

javascriptでサーバー通信をするときに用いられるものとしてはajaxがメジャーですが、Reactで開発している中でajaxのためだけにjQueryを用いるというのはちょっとナンセンスです。

そこで今回はaxiosというサーバー通信用のライブラリを使用します。

Reactでサーバー通信する際は他にもsugaragentfetchが用いられることがありますが、書き方のわかりやすさ、名前のかっこよさから今回axiosをチョイスしました。

ただどのライブラリを使用するにしてもサーバー通信処理を記述する箇所に変わりはありません。

非同期処理用のミドルウェア

React + Redux構成において、stateを書きかえる処理はreducerに記載するのが基本です。しかし、そのstateを書き換えるという処理の都合上、reducerで行われる処理は同期処理でなければならず、ここに非同期のサーバー通信処理を行うことはできません。

そこでactionとreducerの間でサーバー通信を行えるようにするためのミドルウェアであるredux-thunkを導入します。

このミドルウェアを導入することによって、action creater上で関数の呼び出しが可能となります。

サーバー通信をどのタイミングで実装するかという決まりが存在していないため、今回は最もメジャーな手法であるこのaction-reducer間における非同期通信を実装していきます。

サーバー通信を行う為の最低限の構成

ミドルウェアの適用

storeを生成する際に読み込ませることでミドルウェアを実装することができます。

ここでのポイントはファイル構成にかかわらず、createStoreにapplyMiddlewareを使用してredux-trunkをstoreに読み込ませるというところです。

import { createStore, applyMiddleware } from 'redux';
import fromReducer from '../reducers/sample';
import thunkMiddleware from 'redux-thunk'

/* Storeの実装 */

export default function configureStore(){
  return createStore(
    fromReducer,applyMiddleware(thunkMiddleware)
  )
}

アクション

非同期のサーバー通信を実現するために必要なアクションは最低限以下の2つです。

  • 通信開始を伝えるアクション
  • 通信成功時にデータ更新を行うアクション

あとは失敗時に呼び出すアクションがあると便利ではありますが、今回は割愛します。

GETでデータ取得

まずはGETでサーバーからデータを取得するサーバー通信

前述したように、通信開始時、完了時にそれぞれアクションを呼び出しています。

完了時に呼び出されているアクションにおいて、取得したデータをstoreに渡すといったイメージです。

export const FETCH_MESSAGES = 'FETCH_MESSAGES'
export const FETCH_MESSAGES_SUCCESS = 'FETCH_MESSAGES_SUCCESS'

function requestMessages() {
  return {
    type: FETCH_MESSAGES
  }
}

function receiveMessages(json) {
  return {
    type: FETCH_MESSAGES_SUCCESS,
    messages: json
  }
}

// メッセージ取得
export function fetchMessages() {
  return dispatch => {
    dispatch(requestMessages())
    return axios.get('/messages.json').then((response) => {
        dispatch(receiveMessages(response.data))
      }).catch((response) => {
        console.log(response)
      })
  }
}

POSTでデータ送信

POSTでサーバー上のデータを更新する場合も記述箇所、基本的な記述内容は変わりません。

データ送信後、サーバーデータを取得することで現在の画面も最新に更新されます。

export const ADD_MESSAGE = 'ADD_MESSAGE'
export const ADD_MESSAGE_SUCCESS = 'ADD_MESSAGE_SUCCESS'

function addNewMessage() {
  return {
    type: ADD_MESSAGE,
  };
}
function addNewMessageSuccess() {
  return {
    type: ADD_MESSAGE_SUCCESS,
  };
}
// メッセージ送信
export function postMessage(messageBody) {
  return dispatch => {
    dispatch(addNewMessage())
    return axios.post('/messages.json',
    {
      body: messageBody
    },{withCredentials:true}
    ).then((response) => {
        dispatch(fetchMessages())
        dispatch(addNewMessageSuccess())
      }).catch((response) => {
        console.log(response)
      })
  }
}

Reducer

reducerについてはシンプルにサーバー通信用のフラグと取得した値を設定しておきます。

const initialState = {
  messages: [],
  isFetching: false,
};

export default function sample(state = initialState, action) {
  switch (action.type) {
    case 'FETCH_MESSAGES':
    return Object.assign({}, state, {
      isFetching: true
    });
    case 'FETCH_MESSAGES_SUCCESS':
    return Object.assign({}, state, {
      isFetching: false,
      messages: action.messages
    });

    case 'ADD_MESSAGE':
    return Object.assign({}, state, {
      isFetching: true
    });
    case 'ADD_MESSAGE_SUCCESS':
    return Object.assign({}, state, {
      isFetching: false,
    });

    default:
    return state;
  }
}

サーバー通信用メソッドの呼び出し

あとは実際にaxiosでサーバー通信を行っているメソッドを呼び出せばOKです。

GETの場合

データ取得の場合、初期表示についてはレンダリング後にfetchMessagesを呼び出せばstateが更新されます。

またデータ送信成功時にも同じ関数を呼び出しているため、データを追加したは自動的に追加された状態のデータが表示されます。

componentDidMount() {
  this.props.fetchMessages()
}

POSTの場合

フォームで入力した値をサーバーに送信する機能は以下の通りに作成したデータ送信用関数を呼び出せばOKです。

class FormInput extends React.Component {
  send(e) {
    e.preventDefault();
    this.props.postMessage(this.myInput.value);
    this.myInput.value = '';
    return;
  }
  render() {
    return (
      <form>
        <input type="text" ref={(ref) => (this.myInput = ref)} defaultValue="" />
        <button onClick={(event) => this.send(event)}>Send</button>
      </form>
    );
  }
}

まとめ

以上がRedux + Reactでの非同期サーバー通信の実装方法です。

「動かねえぞ!」って言う場合はお問い合わせなどいただければ、できる限り対応いたします。

閲覧いただき、ありがとうございました。

よく読まれている記事

エンジニア入門

2019/4/15

プログラミングの勉強はモチベーションだけでやると挫折する

こんにちは。フリーエンジニアのてぃすです。 最近は未経験からエンジニアを目指したり、エンジニアとしてのキャリアを向上させるために、プライベートでプログラミングを勉強をし始める人が増えてきています。 僕自身、プライベートの時間に未経験言語の勉強をしてキャリアアップした経験があるので、非常にいい傾向だと思っています。 しかしSNSやブログなどを眺めていると、 「この人モチベーションだけで勉強しているな」 という人を多く見かけます。 個人的な経験と人から聞いてきた話から、このようにモチベーションだけで勉強してい ...

続きを読む

エンジニア入門

2019/4/25

絶対にエンジニアになりたい人にオススメするプログラミングスクール3選

こんにちは、フリーエンジニアのてぃすです。 最近はエンジニアの人手不足による給与向上や、自由度の高い働き方に魅力を感じてエンジニア・プログラマを目指す人が増えてきました。 僕の周囲にもプログラミングを始めたいという人が増えてきて、プログラミングスクールとかたくさんあるけどどれがいいの?という質問を受けることがあります。 せっかくなので実際に現場でWeb開発に携わる立場からプログラミングスクールについて比較しながら調べてみました。 そして実際にエンジニアとして働くために最も充実したサービスを提供しているプロ ...

続きを読む

エンジニア独立

2019/4/15

自分の市場価値を把握しようとしないエンジニアは搾取される

こんにちは。フリーランスエンジニアのてぃすです。 エンジニア需要の高まり、待遇の向上からエンジニア・プログラマを目指す人が急増してきている昨今。 確かにエンジニアという職業はこれから高収入・柔軟な働き方を目指そうとした時に、最も適切な選択肢です。 そんな高収入かつ将来性のある職業であるエンジニアですが、自分のエンジニアとしての市場価値を知っておかないと、本来得られるはずの収入よりも少ない額で働くことになる可能性があります。それでも中小企業のサラリーマンよりは稼げますが。 今回は何故市場価値を把握しようとし ...

続きを読む

エンジニア入門

2019/4/28

未経験からプログラミングを学ぶための方法を徹底比較

いまの時代、プログラマという仕事ほどインスタントに高収入を目指せる職業は存在しないと考えています。 未経験の言語での参加にも関わらず、最初から残業なしで手取り30万円を得られた経験を以って、そのことを強く実感しました。 で、最近はプログラマ・エンジニアのこういった稼げる側面に気づいて、プログラマになりたいと考える人多くなってきました。 が、実際にどのような手順を踏んでプログラミングを学習して、プログラマになればいいか分からない人も同様に多いようです。 勉強方法によっては遠回りになりかねない 働きながら勉強 ...

続きを読む

エンジニア独立

2019/4/15

フリーランスエンジニアとして働くことの実情

こんにちは、フリーランスエンジニアのてぃすです。 最近は本業が忙しくブログの更新が滞っておりました。更新を楽しみにしてくださった方々、申し訳ありませんでした。 今後もエンジニアにとって有益な情報を提供できるよう更新を再開していこうと思いますので、引き続きよろしくお願いいたします。 フリーランスエンジニアの実情 このブログではフリーランスエンジニアとして働くことの利点や、実際にどのようなステップでフリーランスエンジニアになるかについての記事をなんども書いてきました。 しかし実際にフリーランスエンジニアとして ...

続きを読む

-プログラミング
-, ,

Copyright© TIS ENGINEER NOTE , 2019 All Rights Reserved Powered by AFFINGER5.