axiosはPromiseベースのHTTPクライアントでReactに限らずフロントエンドのフレークワークで利用することができるだけではなく、バックエンドのNode.jsでも利用することができる便利なライブラリです。バックエンドサーバを含め外部のサービスからデータを取得したい時に利用することができます。本文書ではReact環境におけるaxiosの利用方法について確認していきます。

Reactを使ってaxiosを使う場合どのように設定を行うのか知りたいと思っている入門者の方も多いかと思います。Vue.jsでも同様の文書を公開したところ閲覧してくれている読者の方も多いので今回React版を作成しました。axiosだけでなくReactの基本処理も一緒に理解を深めることができます。

React+axiosを使える環境を構築

Reactプロジェクトの作成はViteを利用して行います。 Viteを利用してプロジェクトを作成後にaxiosのライブラリのインストールを行います。プロジェクト名に任意の名前をつける必要がありますがここではreact-axiosとしています。

 
% npm create vite@latest react-axios -- --template react
Need to install the following packages:
create-vite@5.3.0
Ok to proceed? (y) y


> npx
> create-vite react-axios --template react


Scaffolding project in /Users/mac/Desktop/react-axios...

Done. Now run:

  cd react-axios
  npm install
  npm run dev

プロジェクトの作成が完了したらreact-axiosディレクトリに移動してnpm installコマンドを実行してライブラリのインストールを行います。

開発サーバを起動して動作確認のためにブラウザ上に”Hello Reac”を表示させるためmain.tsxファイルでindex.cssのimportをコメントします。


import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
// import './index.css'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

App.jsxファイルのコードを下記のように更新します。


function App() {
  return (
    <>
      <h1>Hello React</h1>
    </>
  );
}

export default App;

npm run devコマンドを実行して開発サーバを起動してブラウザ上に”Hello React”が表示されることを確認します。

"Hello React"の表示
“Hello React”の表示

JSONPlaceholder

axiosを利用することでAPIを提供するさまざまなクラウドサービス(自社管理のサーバも含む)に対してデータの送受信を行うことができます。無料でAPIを提供しているサービスも多いのでサービスにアカウントを作成することでaxiosの動作確認を行うことも可能ですが、まずはアカウント作成の必要もなく無料で利用できるJSONPlaceholderを使用してaxiosの理解を深めていきましょう。

JSONPlaceholder
JSONPlaceholder

JSONPlaceholderはFree to use fake online REST API for testing and prototypingと説明されている通り、テスト、プロトタイピング目的でREST APIの動作確認をオンラインで行うための無償のサイトです。JSONPlaceholderはフェイクのサーバとして動作するのでaxiosの動作確認用のためにサーバを構築する必要はありません。

axiosの利用方法

axiosとは

axiosはPromiseベースのHTTP ClientライブラリでGETやPOSTのHTTPリクエストを使ってサーバからデータの取得、サーバ上のデータの更新を行うことができます。axiosではなくfetch関数を利用しても同様の処理を行うことができます。

本文書ではアプリケーションを作成する際に必要となる以下の4つのリクエストメソッドについて動作確認を行っています。

  • GETメソッド(データの取得に利用)
  • POSTメソッド(データの追加に利用)
  • DELETEメソッド(データの削除に利用)
  • PATCHメソッド(データの更新に利用)

GETメソッドによるデータ取得

GETメソッドは一番シンプルなメソッドでaxiosのみならず外部から情報を取得する際の基本メソッドです。ブラウザからWEBサーバにアクセスする際もGETメソッドを利用してWEBページに表示する内容を取得しています。

JSONPlaceholderではGETメソッドで取得することができる6つのリソースが準備されています。一番データ取得数の少ないusersから情報を取得してみましょう。

JSONPlaceholderが提供する6つのリソース

ブラウザからhttps://jsonplaceholder.typicode.com/usersにアクセスしてもusersのデータを確認することができるのでaxiosを利用する前にどのような情報が取得できるかを確認することができます。本文書ではidとnameのみ注目します。

ブラウザからのアクセス
ブラウザからのアクセス

axiosのGETメソッドの基本書式は下記のとおりです。getの引数にURLを入れるだけでURLに対してGETリクエストを送ることができます。リクエスト後に戻される値はすべてresponseの中に保存されます。


axios.get('/user?ID=12345')
  .then(function (response) {
 // handle success(axiosの処理が成功した場合に処理させたいことを記述)
    console.log(response);
  })
  .catch(function (error) {
 // handle error(axiosの処理にエラーが発生した場合に処理させたいことを記述)
    console.log(error);
  })
  .finally(function () {
 // always executed(axiosの処理結果によらずいつも実行させたい処理を記述)
  });
async, awaitを利用した場合は上記の基本書式と記述方法が変わり、try,catchを利用します。
fukidashi

axiosの基本書式がわかったのでaxiosのコードを記述していきますが、Appコンポーネントのmount時にaxiosを利用してJSONplaceholderにアクセスを行うためuseEffectフックを利用します。

axiosを利用するためにaxiosライブラリのインストールを行います。


% npm install axios

axiosライブラリをインストールしたらpackage.jsonファイルで動作確認で利用しているReactやaxionsのライブラリのバージョンを確認しておきます。


{
  "name": "react-axios",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.7.2",
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "@vitejs/plugin-react": "^4.3.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react": "^7.34.2",
    "eslint-plugin-react-hooks": "^4.6.2",
    "eslint-plugin-react-refresh": "^0.4.7",
    "vite": "^5.3.1"
  }
}

useEffectの利用方法とデータ取得

useEffectフックとaxiosの基本書式を使ってJSONPlaceholderからusersのデータを取得し、console.logでコンソールに取得した情報を表示します。


import axios from 'axios';
import { useEffect } from 'react';

function App() {
  useEffect(() => {
    axios
      .get('https://jsonplaceholder.typicode.com/users')
      .then((response) => console.log(response))
      .catch((error) => console.log(error));
  }, []);
  return (
    <>
      <h1>Hello React</h1>
    </>
  );
}

export default App;

ブラウザのデベロッパーツールのコンソールにはresponseオブジェクトのdataプロパティに10件分のユーザデータが入っていることが確認できます。response.dataのみ取り出せば配列として全ユーザの情報が取得できます。

responseの中身
usersの情報だけではなくHTTPのステータスコード200やheaders情報も確認することができます。
fukidashi

これでaxiosのGETメソッドの動作確認は完了です。GETメソッドの場合はURLさえわかれば簡単にサーバからデータを取得することができます。

同様の処理をasync, await関数を利用して記述した場合には下記のように記述することができます。


import axios from 'axios';
import { useEffect } from 'react';

function App() {
  useEffect(() => {
    const getUsers = async () => {
      try {
        const response = await axios.get(
          'https://jsonplaceholder.typicode.com/users'
        );
        console.log(response);
      } catch (error) {
        console.log(error);
      }
    };
    getUsers();
  }, []);
  return (
    <>
      <h1>Hello React</h1>
    </>
  );
}

export default App;

axiosのGETメソッドを利用してusers情報を取得しただけなのでブラウザ上に取得したデータが表示されるようにコードを更新します。

useStateを利用したデータの保存

useStateフックを利用してJSONPlaceHolderから取得したユーザの情報を変数usersに保存します。

useStateで定義したsetUsersで取得したresponse.dataをusersに設定します。


import axios from 'axios';
import { useEffect, useState } from 'react';

function App() {
  const [users, setUsers] = useState([]);
  useEffect(() => {
    axios
      .get('https://jsonplaceholder.typicode.com/users')
      .then((response) => setUsers(response.data))
      .catch((error) => console.log(error));
  }, []);

useStateを利用してusersに保存したデータをブラウザに表示させます。usersに保存された情報を展開するためにmap関数を利用し、名前が保存されているnameのみ表示させます。


return (
  <>
    <ul>
      {users.map((user, index) => (
        <li key={index}>{user.name}</li>
      ))}
    </ul>
  </>
);

ブラウザで確認するとaxiosで取得したユーザ名の一覧を確認することができます。

getメソッドで取得したユーザ一覧
getメソッドで取得したユーザ一覧

useEffectでmount時にJSONPlaceholderからデータを取得しuseStateでデータを保存しそのデータをブラウザ上に表示することができるようになりました。サーバから取得したデータをReactで表示させたい場合はここまでの処理で完了です。

POSTメソッドによる新規作成

サーバ側でPOSTリクエストを受け付けている場合はaxiosのPOSTリクエストを使うと新規にデータを作成することができます。POSTの場合はGETとは違いデータを作成するのに新規のデータを作成するために必要となるプロパティと値のペアを事前に確認しておく必要があります。

JSONPlaceholderのホームページにはPOSTリクエストの受付は/postsのみしか記述されていませんが、/usersでも動作することを確認しました。/usersが使えない場合はJSONPlaceholderのガイドを確認し/postsへのPOSTリクエストで動作確認を行ってください。
fukidashi

POSTメソッドの場合は、オブジェクトを利用して下記のように記述することができます。firstName, lastNameの項目を持つデータを追加しようとした場合はオブジェクトにfirstNameとlastNameプロパティを設定し、各プロパティに値を設定します。2つ以上の項目がある場合は、同様の方法で必要なプロパティと値のペアを追加します。


axios.post('/users', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

input要素からのデータ追加

実際のアプリケーションを構築する場合は新規のデータを追加する場合はユーザが入力フォームに追加した情報を登録するのがほとんどです。本文書ではinput要素を利用してデータの追加機能を実装します。

新たにuseStateでnameを定義します。


const [name, setName] = useState('')

input要素にonChangeイベントを設定し文字を入力するとhandleChangeメソッドが実行されます。ボタンにクリックイベントを設定し、ボタンをクリックするとcreateNewUserメソッドが実行されます。


<div>
  <input value={name} onChange={handleChange} /><br />
  <button onClick={createNewUser}>作成</button>
  <ul>
    {users.map((user, index) => (
      <li key={index}>{user.name}</li>
    ))}
  </ul>

イベントで指定したhandleChange、createNewUserメソッドを追加します。

handleメソッドではsetNameを使って入力した値をevent.target.valueから取り出しnameを更新します。

createNewUserではaxiosのPOSTメソッドを使って、入力値であるnameをJSONPlaceholderに送信します。JSONPlaceholderからは送信した値が戻ってくるので戻った値(入力したname)をusersに追加します。


const handleChange = (e) => {
  setName(e.target.value)
}

const createNewUser = () => {
  axios.post('https://jsonplaceholder.typicode.com/users', {
    name: name
  })
  .then(response => {
    setUsers([...users, response.data])
  })
  .catch(error => {
    console.log(error);
  });
}

ブラウザで確認するとinput要素と”作成ボタン”が表示されます。フォームにJohn Doeを入力して”作成ボタン”をクリックするとユーザ一覧の最後に”John Doe”が追加されます。

POSTリクエスト前
POSTリクエスト前

作成ボタンを押すと一番下にJohn Doeが表示されていることが確認できます。

usersに入力した値が追加される
usersに入力した値が追加される
JSONPlaceholderはPOSTメソッドを使って動作確認は行うことができますが、ユーザを追加してもJSONPlaceholder上のユーザデータが10から11に増えるわけではありません。その代わり、追加したデータはresponse.dataの中に入って戻ってきます。JSONPlaceholderの場合は追加したユーザを戻すという仕様です。他のサービスの場合ではどのような情報が戻ってくるのか確認する必要があります。
fukidashi

DELETEメソッドによるデータの削除

axiosのDELETEメソッドを利用してデータの削除方法を確認します。GETメソッドとは異なりDELETEするデータを識別するIDが必要となり書式は下記のとおりです。


axios.delete('/user/{id}')
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .finally(function () {
    // always executed
  });

各リストの行に”削除ボタン”をつけて、ボタンを押すとdeleteUserメソッドが実行できるように変更を行います。引数には削除するユーザを識別するためのuserのidを設定します。


<ul>
  {users.map((user, index) => (
    <li key={index}>{user.name}:<button onClick={() => deleteUser(user.id)}>削除</button></li>
  ))}
</ul>

deleteUserメソッドの追加を行います。deleteメソッドをJSONPlaceholderに実行してもサーバ上のデータが削除されるわけではありません。またJSONPlaceholderから戻されるdataは{}なので戻されてきたデータを使って何か処理を行うことができません。ここではdeleteに成功した場合にusers(配列)から削除したユーザのIDを持つ要素を削除しています。filter関数を利用し、削除したユーザのIDと一致しない要素のみ取り出しています。


const deleteUser = (id) => {
  axios.delete(`https://jsonplaceholder.typicode.com/users/${id}`)
  .then(response => {
    console.log(response)
    setUsers(users.filter(user => user.id !== id))
  })
  .catch(error => console.log(error))
}
削除ボタンが名前の横に表示
削除ボタンが名前の横に表示

削除ボタンを押すとJSONPlaceholderにdeleteメソッドが送信されます。deleteメソッドに成功すると”削除ボタン”を押したユーザが削除されます。

2ユーザを削除
2ユーザを削除

JSONPlaceholderから戻される値を確認するとdeleteメソッドでステータスコードが200であることがわかります。説明した通り、dataには空のオブジェクトになっているのでこのデータからではどのユーザを削除したかはわかりません。

deleteメソッドで戻される値
deleteメソッドで戻される値

PUTメソッドによるユーザの更新

axiosのPATCHメソッドを利用してデータの更新方法を確認します。PATCHメソッドではサーバに保存されている既存のデータの上書きを行うので更新したい項目と値のペアを指定する必要があります。また更新するユーザを一意に識別することができるIDなどの情報が必須となります。


axios.patch('/user/{id}',{
   firstName: 'Jone',
   lastName : 'Dow'
  })
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .finally(function () {
    // always executed
  });

ユーザ情報を更新するためには更新フォームが必要となりますが本文書ではaxiosの動作確認に注目しているので各行に”更新ボタン”を設定してボタンを押すと名前が”John Doe”に更新される設定を行います。

”削除ボタン”の横に”更新ボタン”を追加します。


<ul>
  {users.map((user, index) => (
    <li key={index}>{user.name}:
      <button onClick={() => deleteUser(user.id)}>削除</button>
      <button onClick={() => modifyUser(user.id)}>更新</button>
    </li>
  ))}
</ul>

クリックイベントで設定しているmofidyUserメソッドを追加します。PATCHメソッドでは更新したい項目と値のみ設定を行います。ここではnameプロパティに’John Doe’を持つオブジェクトを設定しています。JSONPlaceholderではPATCHメソッドを実行すると指定したidを持つユーザの情報が戻されます。戻された情報を利用して更新したIDを持つユーザ情報のみmap関数を利用して入れ替えを行っています。


  const modifyUser = (id) =< {
    axios.patch(`https://jsonplaceholder.typicode.com/users/${id}`, {
      name: 'John Doe'
    })
    .then(response =< {
      let updateUsers = users.map(user =< {
        if(user.id === response.data.id){
          return response.data
        }else{
          return user;
        }
      })
      setUsers(updateUsers)
    })
    .catch(error =< console.log(error))
  }
JSONPlaceholderではPATHCHメソッドで更新したユーザの情報すべてが戻されますが戻される情報はアプリケーションによって異なります。
fukidashi

実際に動作確認を行うと

削除ボタンが表示される
更新ボタンが削除ボタンに表示される

3番目のユーザの”更新ボタン”を押すと”John Doe”に変更されることが確認できます。その他のユーザの更新ボタンを押しても名前は”John Doe”に変わります。

3番目のユーザがJohn Doeになっていることを確認
3番目のユーザがJohn Doeになっていることを確認

axiosを利用してPATCHメソッドを利用する方法も確認することができました。

エラーについて

これまでの処理はすべて成功していたのでエラーについては何も説明を行っていませんでした。意図的にエラーを発生させその場合にどのようなことが発生するのか確認しておきましょう。

deleteメソッドを送信するURLをusersからuserに変更します。つまり存在しないURLにdeleteメソッドを送信します。


axios.delete(`https://jsonplaceholder.typicode.com/user/${id}`)

エラーが発生するとcatch(error..)の中身が実行されるのか確認しerror.responseでエラーの内容を確認します。


const deleteUser = (id) => {
  axios.delete(`https://jsonplaceholder.typicode.com/user/${id}`)
  .then(response => {
    console.log(response)
    setUsers(users.filter(user => user.id !== id))
  })
  .catch(error => {
    console.log('エラーが発生')
    console.log(error.response)
  })
}

エラーが発生するとcatchの内容が実行されていることが確認できます。ステータスコードが404と表示され、エラーがなく処理が成功している場合のステータスコード200, 201とは異なることも確認できます。

エラー内容を確認
エラー内容を確認

エラーが発生した場合はcatch句の中でエラー処理を設定することになります。

React環境でaxiosの基本メソッドであるGET, POST, DELETE, PATCHの利用方法を理解することができました。