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

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

Reactのプロジェクトを作成してからaxiosライブラリをインストールすることで環境を構築することは可能ですが、手軽に動作確認したいのでcdnを利用してaxiosの動作確認を行っていきます。任意のフォルダにindex.htmlファイルを作成し、下記のコードを記述してブラウザ上にHello Reactが表示されることを確認してください。


<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Reactを使ってaxiosを学ぶ</title>
	<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
<script type="text/babel">
  const App = () => {
    return (
      <div>
       <h1>Hello React</h1>
      </div>
    );
  }
  ReactDOM.render(<App />, document.getElementById('root'))
</script>
</body>
</html>
Reactをcdnで利用する場合はreact、react-domが必須です。またJSXを利用する場合はbabelも必要となります。scriptタグのtype属性にtext/balelを追加してください。

ブラウザ上に下記が表示されればcdnを利用したコードは正常に動作しています。

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のみならず外部から情報を取得する際の基本メソッドです。通常のブラウザでサーバにアクセスする際もGETメソッドを利用しています。

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の処理結果によらずいつも実行させたい処理を記述)
  });

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

axiosを利用するためにaxiosのCDNを忘れずに追加します。


<script src="https://unpkg.com/axios/dist/axios.min.js"></script> 
Reactプロジェクトの場合はaxiosのライブラリをインストールしてimportすることになります。

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

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


<script type="text/babel">
  const { useEffect } = React
  const App = () => {
    useEffect(() => {
      axios.get('https://jsonplaceholder.typicode.com/users')
        .then(response => console.log(response))
        .catch(error => console.log(error))
    }, [])
    return (
      <div>
       <h1>Hello React</h1>
      </div>
    );
  }
  ReactDOM.render(<App />, document.getElementById('root'))
</script>
CDNでuseEffectを利用するためにconst {useEffect} = Reactが必須となります。この1行がない場合は、Uncaught ReferenceError: useEffect is not defineエラーが表示されます。

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

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

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

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

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

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

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


const { useState, useEffect } = React
const 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のみ表示させます。


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

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

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

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

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

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

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

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の場合は追加したユーザを戻すという仕様です。他のサービスの場合ではどのような情報が戻ってくるのか確認する必要があります。

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メソッドで更新したユーザの情報すべてが戻されますが戻される情報はアプリケーションによって異なります。

実際に動作確認を行うと

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

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の利用方法を理解することができました。