はじめに
前々回のReactを使用してWeb画面を作成するでは、reactの簡単なサンプルと共に説明をまとめました。
前回のReduxとReduxToolkitを使用してReact内でデータを管理するでは、reduxのの簡単なサンプルと共に説明をまとめました。
今回はaxiosを使用してREST APIから情報を取得して画面に表示させるサンプルと説明をまとめようと思います。
環境
- node.js: v12.18.2
- webpack: 4.44.1
- React: 16.13.1
- Redux: 7.2.1
- axios: 0.19.2
環境作成
前回のReactを使用してWeb画面を作成すると前回のReduxとReduxToolkitを使用してReact内でデータを管理するの続きとなります。
環境構築などはそちらを見てください。
axios
REST APIへ通信するためにaxiosというライブラリを使用します。
axiosのインストール
npm install axios
Redux Thunk
axiosは非同期で通信を実行します。しかし、Reduxは非同期の処理をするのは若干手間です。それらを楽にするためにRedux Thunkというミドルウェアを使用します。
Redux Thunkのインストール
npm install redux-thunk
Babel/polyfill
axiosを使用するにあたってpolyfillが必要になります。
Babel/polyfillのインストール
npm install @babel/polyfill --save-dev
Reactでaxiosを使用する
Reactのソースの作成
前回のReduxとReduxToolkitを使用してReact内でデータを管理するの続きなので、ソースも前回のに対して変更していく形にします。
sliceファイルにREST API呼び出しの処理を追加
REST APIの呼び出しと呼び出した後の処理をsliceファイルに追加する。
今回呼び出すREST APIはhttp://localhost:3000/mess_api
、ボディは{["message":"testMessage"]}
を想定して、このtestMessageをstateのmessに入れて、画面に表示させます。
import { createSlice } from '@reduxjs/toolkit';
import axios from 'axios';
export const messageSlice = createSlice({
name: 'message',
~~~ 前回と同じ ~~~
reducers: {
~~~ 前回と同じ ~~~
// action内にREST APIから取ってきたデータが入っている
getRequest: (state, action) => {
// body内の最初のmessageキーの値をstateに入れる
state.mess = action.payload[0].message;
}
},
});
// 今回追加したgetRequestもエクスポートする
export const { sayhello, sayAmount, getRequest} = messageSlice.actions;
// RESTAPIの発行とgetRequestの呼び出しをする
export const getRequestAsync = amount => async dispatch => {
// ここでREST APIの呼び出しをする
const response = await axios.get('http://localhost:3000/mess_api').then(response => {
// 呼び出した結果のボディだけgetRequestに与える(与えるものを返れば上のaction引数に入る内容も変わる)
dispatch(getRequest(response.data));
});
};
export default messageSlice.reducer;
storeファイルにthunkを追加
import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
import messageReducer from './slice/messageSlice';
export default configureStore({
reducer: {
message: messageReducer,
},
middlewares: thunk
});
slice経由でstoreを使用する
コンポーネントでREST APIを発行する際には、sliceで作成したactionを呼び出してstoreを操作します。
import React, { useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { sayhello, sayAmount, getRequestAsync } from '../store/slice/messageSlice';
export function Message() {
const message = useSelector(state => state.message.mess);
const dispatch = useDispatch();
const [messsageAmount, setMesssageAmount] = useState('2');
~~~ 前回と同じ ~~~
{/* sliceで作成したgetRequestAsyncアクションを使用する */}
<button aria-label="rest get" onClick={() => dispatch(getRequestAsync())}>
通信
</button>
{/* テキストボックスとボタンにインポートしたものを適用する */}
<input aria-label="set amount" value={messsageAmount} onChange={e => setMesssageAmount(e.target.value)} />
<button onClick={() => dispatch(sayAmount(messsageAmount))}>
テキスト変更
</button>
</div>
</div>
);
}
Reactの実行
前回同様にReactを開発用のサーバで起動してブラウザからアクセスしてください。
"./node_modules/.bin/webpack-dev-server"
通信ボタンを押すとREST APIを発行して、そのボディをstoreに格納することでWeb画面上のテキストも変わります。
REST APIサーバを立てる
REST APIさえ発行できれば何を使用しても良いのですが、手ごろな環境がない場合に簡単なREST APIサーバを立てる方法もまとめます。
node.jsがある環境なのでJSON Serverというライブラリを使用してREST APIを立てます。
JSON Serverのインストール
npm install -g json-server
JSON用ファイルの作成
JSONのエンドポイントとボディを定義したファイルをJSON形式で作成します。
今回はReactからエンドポイント:mess_api
、ボディのキー:message
から情報を取っているためそのように記載します。
{
"mess_api": [
{ "id": 1, "message": "testMessage" }
]
}
JSON Serverの起動
先ほど作成したJSON用ファイルを指定してJSON Serverを起動します。
json-server --watch db.json
コンソールに起動した旨が表示されればREST APIサーバの完成です。
終わりに
ReactのWeb画面作成に関しては、ここで一旦終わりにしようかと思います。React Routerなど他のライブラリもReactにありますが、特に難しくなかったのでまとめなくて良いかなと思います。
REST APIに通信できるようになるとWeb画面で出来ることが増えるため、とても便利だと思います。しかし、Reactでのaxiosの使い方とReduxでのaxiosの使い方が結構違うので苦労しました。
次回はreact-testing-libraryの使い方でもまとめてみようと思います。