Axiosを使ってReact+TypeScriptからHTTPリクエスト(GET/POST/PUT/DELETE)を送信する

#はじめに
都内の企業でITエンジニアをしています。
最近、フロント（React+Next.js+TypeScript）からAPIサーバへHTTPリクエストを送信する処理を実装したのですが、様々な記事を参考にしたため、忘れないようにまとめておきます。

#Axiosを使用してできること
- クライアント側からサーバ側へHTTPリクエストを送信する

※HTTPリクエストとは、GET,POST,PUT,DELETEの各自メソッドのことです。

#前提として
この記事では以下を前提としています。

- 開発言語は、React+TypeScript
- APIサーバについては各自用意
- 関数コンポーネント推奨

#Axiosを使用する準備①Axiosのインストール
まずはターミナルにて、以下のコマンドを実行してAxiosをインストールします。

```
npm install axios
```

もしくは

```
yarn add axios
```

#Axiosを使用する準備②プロジェクトフォルダの構成
プロジェクトフォルダ内のフォルダ構成は以下とします。
※最低限しか記述していません。

```
プロジェクトフォルダ
   └┬ .next
    ┝ node_modules
    ┝ package.json
    ┝ package-lock.json
    ┝ README.md
    ┝ tsconfig.eslint.json
    ┝ tsconfig.json
    └ src
        └┬ interfaces 
         ┝ pages
         |   └ index.tsx
         ┝ services
         ┝ styles
         ┝ utils
         └ component
             ┝ atoms
             ┝ molecules
             ┝ organisms
             └ templates

```

#Axiosを使用する準備③リクエストURLを別モジュールに定義しておく

APIへ送信するリクエストURLを定義しておくモジュールを作成します。

「Axiosを使用する準備②」の「utils」直下にファイルを作成します。

```Requests.tsx
const requests = {
  fetchSampleData: 'http://000.0.0.0:0000/SampleData',  // GETメソッド
  InsertSampleData: 'http://000.0.0.0:0000/SampleData',  // POSTメソッド
  UpdateSampleData: 'http://000.0.0.0:0000/SampleData',  // PUTメソッド
  DeleteSampleData: 'http://000.0.0.0:0000/SampleData',  // DELETEメソッド
};

export default requests;
```

- http: //000.0.0.0:0000/SampleDataの部分は、APIへ送信するリクエストURLを指定します。


#GETメソッド(データ取得)の実装
まずは、GETメソッドを使用して、サーバからデータを取得するプログラムになります。

- APIから取得するキー値は「user_id」「user_name」「club_code」「club_name」とします。
- SampleTypeという名称のインタフェース(連想配列のようなイメージ)を定義していることを前提とします。これはGETで取得したデータを受け取るために使用します。

```src/interfaces.tsx
export type SampleType = {
  userId: string;
  userName: string;
  clubCode: string;
  clubName: string;
};
```

こちらがメインのコンポーネントです。

```src/pages/index.tsx
import { FC, useState, useEffect } from 'react';
import axis from 'axios';
import requests from 'utils/Request';
import SampleType from 'interfaces';

const Sample: FC = () => {
  const [info, setInfo] = useState([]);
  const datad: SampleType[] = [];

  useEffect(() => {
    const getSampleData = () => {
      axis
        .get(requests.fetchSampleData)  // GETメソッドを呼び出す
        .then((res) => {  // レスポンスを受け取ったらthenを実行する

          // GETで取得したデータをforEachでループしてStateにセットする
          res.data.forEach((resData) => {
            const data: SampleType = {
              userId: resData["user_id"],
              userName: resData["user_name"],
              clubCode: resData["club_code"],
              clubName: resData["club_name"],
            };
            datas.push(data);
          });
          setInfo(datas);
        })
        .catch((error) => {  // エラーコードが返ってきた場合
          console.log(error);  // エラーコードを表示
        });
      };

    getSampleData();  // 関数を実行する
  }, []);

  return (
    <>
      // ここにTSX、もしくはJSXを記述する
    </>
  )
};

export default Sample;
```

#POSTメソッド(データ登録)の実装
次は、POSTメソッドを使用して、サーバへデータを登録するプログラムになります。

処理の内容は、SAVEボタンを押下すると、configuration_nameが[configurationNameの入力値]であるデータを登録します。

```src/pages/index.tsx
import { FC, useState } from 'react';
import axis from 'axios';
import requests from 'utils/Request';
import { TextField } from '@material-ui/core';

const SampleSave: FC = () => {
  const [configurationName, setConfigurationName] = useState('');

  // Saveボタン押下
  const onClick = (event: Event) => {
    event.preventDefault();

    axis.post(requests.InsertSampleData, {
      configuration_name: configurationName,
    })
    .then(red => {
      // ここで返って来た結果に対して処理を行う
    })
    .catch((error) => {
      console.log(error);
    });
  };

  // テキストボックスの値が変更された時Stateを更新する
  const onChangeValue = (event: ChangeEvent<HTMLInputElement>) => {
    event.preventDefault();
    setConfigurationName(event.target.value);  // 値をStateへセットする
  };

  return (
    <>
      <TextField
        value={configurationName}
        onChange={onChangeValue}
      />

      <Button
        text="SAVE"
        onClick={onClickUpdate}
      />
    </>
  )
};

export default Sample;
```

#PUTメソッド(データ更新)の実装
次は、PUTメソッドを使用して、サーバ上のデータを更新するプログラムになります。

処理の内容は、UPDATEボタンを押下すると、configuration_nameの値を[configurationNameの入力値]に更新します。

```src/pages/index.tsx
import { FC, useState } from 'react';
import axis from 'axios';
import requests from 'utils/Request';
import { TextField } from '@material-ui/core';
import Button from '@material-ui/core';

const SampleUpdate: FC = () => {
  const [configurationName, setConfigurationName] = useState('');

  // UPDATEボタン押下
  const onClick = (event: Event) => {
    event.preventDefault();

    axis.put(requests.UpdateSampleData, {
      configuration_name: configurationName,
    })
    .then(red => {
      // ここで返って来た結果に対して処理を行う
    })
    .catch((error) => {
      console.log(error);
    });
  };

  // テキストボックスの値が変更された時Stateを更新する
  const onChangeValue = (event: ChangeEvent<HTMLInputElement>) => {
    event.preventDefault();
    setConfigurationName(event.target.value);  // 値をStateへセットする
  };

  return (
    <>
      <TextField
        value={configurationName}
        onChange={onChangeValue}
      />

      <Button
        text="UPDATE"
        onClick={onClickUpdate}
      />
    </>
  )
};

export default Sample;
```

#DELETEメソッド(データ削除)の実装
次は、DELETEメソッドを使用して、サーバ上のデータを削除するプログラムになります。

処理の内容は、DELETEボタンを押下すると「user_id='100'」のデータを削除します。

```src/pages/index.tsx
import { FC, useState } from 'react';
import axis from 'axios';
import requests from 'utils/Request';
import Button from '@material-ui/core';

const Sample: FC = () => {
  const [configurationName, setConfigurationName] = useState('');

  // DELETEボタン押下
  const onClickDelete = (event: Event) => {
    event.preventDefault();

    axis.post(requests.UpdateSampleData, {
      data: {
        user_id: '100',
      }
    })
    .then(red => {
      // ここで返って来た結果に対して処理を行う
    })
    .catch((error) => {
      console.log(error);
    });
  };

  return (
    <>
      <Button
        text="DELETE"
        onClick={onClickDelete}
      />
    </>
  )
};

export default Sample;
```

#参考
- [axiosで非同期通信(React+TypeScript使用](https://naokeyzmt.com/rogue/axios-typescript-es6)
- [React でAxios を使用する方法](https://www.digitalocean.com/community/tutorials/react-axios-react-ja)


#まとめ

- React+TypeScriptでHTTPリクエスト(GET/POST/PUT/DELETE)を送信する場合、axios使用すると比較的簡単に実装ができる。