Reactでのaxiosの使い方【外部APIの取得方法】

本稿ではaxiosというフロントエンドとAPI間の通信ライブラリーについてご紹介したいと思います。AxiosはReactのクラスコンポーネントでも動くのですが、この記事では、Reactの関数コンポーネント内でaxiosを使用する方法をご紹介しています。

さてaxiosですが、githubのaxiosのページでは、ブラウザとnode.jsのためのプロミスベースのHTTPクライアントとあります。

Promise based HTTP client for the browser and node.js

https://github.com/axios/axios

JavaScriptには、同様にPromiseを返すfetch APIが備わっていますが、fetch APIの場合は、responseがjsonではないので、毎回responseをjsonに変換しなくてはなりません。他方、axiosはjsonが直接得られるのでコードがよりシンプルになります。また、リクエストの共通URL部分及びヘッダーをインスタンスで設定できる点もaxiosの魅力です。

axiosのインスタンスの作成方法

Reactでaxiosを使用するためには、まずnode.jsのnpmを使ったインストールが必要です。

npm install axios

続いて、外部APIのURLに共通部分があるケースを想定し、axiosのインスタンスを作成します。インスタンスはGETリクエストのコードを記述するファイルに直接書いてももちろんいいのですが、ここでは別ファイルに書いてインスタンスをエクスポートする例をご紹介します。また、本記事ではTMDBという映画のAPIを例にご紹介します。

下記が具体的なコードです。1行目で先ほどインストールしたaxiosをインポートし、3-5行目でaxiosのインスタンスを作成、最後の行で作成したインスタンスをエクスポートしています。3-5行目では、インスタンスにbaseURLという属性を設定し、同属性の値として外部APIの共通部分のURLを記入します。このファイルはaxios.jsという名前で保存します。

axios.js

import axios from "axios";

const instance = axios.create({
baseURL: "https://api.themoviedb.org/3",
});

export default instance;

続いて、各APIエンドポイントに固有のURLを格納するオブジェクトを作ります。こちらも、GETリクエストを記述するファイルと同じファイルに書いてもいいのですが、別ファイルRequests.jsに書く例をご紹介します(メンテナンスが容易になります)。

下記1行目でAPI_KEYを設定します(API_KEYがない場合はこの部分は不要です)。API_KEYは通常はprocess.envに格納しますが、ここでは見やすいようにファイル内の変数(定数)に格納します。なお、下記APIキーは架空の値ですので、実際にTMDBで試される場合はAPIを取得してください。

3-6行目でrequestsというオブジェクトに、キーを任意のAPIの名称、値に同APIエンドポイントに固有URLを格納しています。TMDBには非常に多くのAPIが用意されていますが、ここではトレンド映画のAPIと高評価映画のAPIの2つを設定しています。

両者は、先ほど設定したbaseURLが共通で、後ろに続く部分が別々ということになります。

Requests.js

const API_KEY = "abcdefghij123456789101112131";

const requests = {
fetchTrending: `/trending/all/week?api_key=${API_KEY}&language=en-US`,
fetchTopRated: `/movie/top_rated?api_key=${API_KEY}&language=en-US`,
};

export default requests;

TMDBを使った本事例には不要ですが、axiosのインスタンスに下記のようにヘッダーを含めることも可能です。

axios.js

import axios from "axios";

const instance = axios.create({
baseURL: "https://api.themoviedb.org/3",
headers: {
Authorization: `token YOURTOKEN` });

export default instance;

axiosを使った外部APIデータの取得方法

準備が整ったので、いよいよReactの関数コンポーネント内で、axiosを使用して外部APIからデータを取得したいと思います(下記参照)。ここではReactの関数コンポーネントのHooksのうち、useStateとuseEffectを使用しますので、1行目で両者をインポートしています。関数コンポーネントとstateについては以前書いたこちらの記事で概要を解説しております。

2行目では先ほど作ったaxios.jsファイルからaxiosインスタンスをインポートし、3行目では同じく先ほど作ったRequests.jsファイルからrequestsをインポートしています。

Reactの関数Appの内側の1行目で、useStateを使って、外部APIからのデータを格納するための変数 movieを宣言しています。このAPIは結果が配列で帰ってくるので、初期値は空の配列としています。続くuseEffect関数がaxiosによる外部APIとの接続部分です。ややわかりにくいかもしれませんが、useEffect内でfetchDataという非同期関数を設定して、実行するというのがこの部分の基本的な構造です。

この事例では、初回読み込み時にのみAPIからデータを取得するので、useEffect関数のdependency arrayを空にしています(最後の角括弧[]の部分)。ユーザーのインプットやpropsの値に応じてAPIのエンドポイントを変える場合には、dependency arrayに同変数部分を入れる必要があります。

App.js

import React, { useState, useEffect } from "react";
import axios from "./axios";
import requests from "./Requests";

function App() {
const [movie, setMovie] = useState([]);

useEffect(() => {
async function fetchData() {
const response = await axios.get(requests.fetchTrending);
setMovie(response.data.results);
return response;
}

fetchData();
}, []);

return (
< div className="app">
{movie}
< /div>
);
}

export default App;

非同期(async await)のfetchData関数の内側では、axios.getの引数としてrequests.fetchTrendingを渡しています。この部分でaxios.jsのインスタンスで設定したbaseURLとRequests.jsで設定したURLの固有部分を繋げてGETリクエスト送っています。得られるjsonはresponseに格納しています。

useStateのsetMovieによって、movie変数にjsonの値を格納しています。useState内の.resultsの部分は、APIから得られるレスポンスのjsonを見ながら毎回設計する必要がありますが、axiosにおいては.dataによりレスポンスのjsonが得られる点まではどのようなAPIに対するリクエストでも共通です。return responseの行は一応fetchData関数の戻り値としてrenponseを返していますが、機能的には不要です。

また、本稿には直接関係ありませんが、useEffect関数はそのものをasync関数に出来ないので、本事例のようにuseEffectの内部で非同期のawaitを使いたい場合は、useEffectの内部でasync関数を定義して実行する(fetchData();の部分)という形にする必要があります。

AppはReactの関数コンポーネントですので、App関数の戻り値はJSXです。ここでは単純にmovieの配列をそのまま表示させています。

axiosのパラメーター設定

先ほどのApp.jsにおけるaxios.getの引数はurlであるrequests. fetchTrendingのみでしたが、axiosのリクエストにボディーとヘッダー等のコンフィグレーションを含めることも可能です。以下ではasync functionの内側のみを表示しています。awaitはasyncの内側でしか使えませんのでご注意ください。

await axios.get(url, data, config);

その場合は、第一引数にurl、第二引数にbody(オブジェクト)、第三引数にconfig(オブジェクト)を指定します。第三引数は省略可能です。また、第二引数のbodyがなく、その他configがある場合は同configを第二引数とします。具体的には下記のようになります。

// body(data)変数
const data = {
key: "value"
};

// config変数
const config = {
headers: {
Authorization:
"JWT " + "yourJWTtoken",
},
};


//axiosにbodyとconfigの両方を含む場合
await axios.get(requests.fetchTrending, data, config);

//axiosにconfigのみを含む場合
await axios.get(requests.fetchTrending, config);

この例では、bodyとしてkey:”value”を指定、configにはheaderとしてJWTのAuthorizatrionを指定しています(前述の通り、headerはインスタンスで設定することも可)。header内にはcontent-type等他の内容も指定することができます。またconfigには、timeoutなどaxiosのその他configオプションの指定が可能です。

クエリパラメーターの設定方法 – URLSearchParams

クエリパラメーターはURLに直接打つ方法でも問題ないですが、コードを見やすくするためにURLSearchParams()クラスを使用することもでいます。URLSearchParams()クラスは、axiosの機能ではなくJavaScript固有のクラスですので、インポートせずに使えます。下記の例はgithub apiの例です。本APIエンドポイントのクエリパラメーターqに対して、テキスト(下記では”Thomas”)を設定すると、githubユーザー名に”Thomas”を含むユーザーの一覧が得られます。このエンドポイントのパラメーターは1つですが、クエリパラメーターが複数ある場合はURLSearchParamsオブジェクト内に複数並べることができます。

// クエリパラメーターの設定
const params = new URLSearchParams({
q: "Thomas",
})

// config変数
const config = {
headers: {
Authorization:
`token YOURTOKEN`,
},
};

await axios.get(`https://api.github.com/search/users?${params}`, config);
const data = response.data.items;

今回GETリクエストで紹介しました。axiosの使い方はPOST(axios.post)やPUT(axios.put)でも同様です。POSTリクエストについては、stackoverflowのこちらの議論がわかりやすいです。今日も最後まで読んで頂きありがとうございました。

今回ご紹介しなかったerrorのcatchを含むaxiosの使い方は、私の下記動画で詳しく解説しております。宜しければこちらもご覧になってみてください。