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

【地方も強いフリーランスエージェント】PE-BANKを徹底分析

ITエンジニアという職業の魅力についてはこのブログでなんども書いていますが、その中でもフリーランスエンジニアという働き方は、 年収1000万以上も珍しくない高収入 リモートワークや時短勤務などの自由な働き方 を実現する可能性を秘めています。 しかし有名どころのエージェントは基本的に都内、関東のみしか扱っていないケースが多いです。 また現状ITエンジニアがフリーランスとしてやっていく場合、都内で働くことが案件数・単価の都合上もっとも効率がいいです。 しかし地元に愛着があったり、離れることが難しい状況下にある ...

続きを読む

エンジニア独立

2019/4/15

正社員エンジニアという働き方を批判してみる

今回はちょっと過激めなタイトルを飾ってみました。 僕はエンジニアとして、正社員・派遣社員・フリーランスとして働いて来ていますが、その中でどうしても正社員という働き方がもてはやされている理由が分からないんですよね。 とはいえ有名理系大卒で競争力激高な大手企業のスーパーエンジニアだったり、激レアホワイト企業に勤めている人に反論されたらぐうの音も出ないというか、論点が変わってきてしまうので、以下の条件に当てはまるような正社員エンジニアに向けてのお話ということで読み進めていただければなと。 20代で年収400万円 ...

続きを読む

エンジニア独立

2019/4/15

ITエンジニアが給与上げるために出来ることは限られている

どうも、フリーランスエンジニアのてぃすです。 今ITエンジニアってかなり稼げる職種として知られてきていますが、中にはその影響を感じられていない人もいるんじゃないかと思います。 ぼくは2年の間に正社員、派遣、フリーランスと渡り歩いて、月収は20万→40万→80万->100万と変動してきました。 その中でITエンジニアとして収入を上げるために出来ることがなんなのかが少しずつ見えてきました。 今回はその経験から感じたITエンジニアが収入を上げるために出来ることについて分析・解説していきます。 会社の中で給 ...

続きを読む

エンジニア独立

2019/4/15

ITエンジニアの働き方比較(正社員/派遣/フリーランス)

最近ではITエンジニアの需要が激増し、特にプログラマーを目指す人が増えてきました。 今の時代、プログラマーをはじめとするITエンジニアを仕事として選ぶことは賢明かつ的確な判断と言えるでしょう。 その一方で、世間ではプログラマーの不遇が叫ばれていたり、IT土方などの蔑称で呼ばれていたりします。 それは働き方の選択を誤っているプログラマーがあまりに多いことが原因となっています。 稼げる市場であるということは、依頼主と技術提供者の間に入って、不当に利益を得ようとする存在が増えることに繋がります。そういった存在に ...

続きを読む

エンジニア独立

2018/10/9

プログラマー・エンジニアが情報発信をするべき2つの理由

こんにちは。フリーエンジニアのてぃすです。 プログラマー・ITエンジニアとして働いている人が、SNSやブログで積極的に技術的なTipsや働き方に関する考え方を発信しているのをよく見ると思います。 情報発信をしたことのない人からすると、なんでそんな一銭の得にもならない行為をやっているのか、という疑問も湧いてくるでしょう。 知っている人は知っていることですが、エンジニアにとって情報発信ってすごいメリットがある行為なんです。 そこで今日はプログラマー・ITエンジニアが今すぐにでも情報発信を始めるべき2つの理由を ...

続きを読む

-プログラミング
-, ,

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