ReactでAPIを叩いたときに429が返ってきた話

# はじめに
楽天のAPIを使ってReactのアプリケーションを作ろうと思ってたんですが、まぁー詰まった。。

https://webservice.rakuten.co.jp/

APIを1回しか叩いていないのに429返ってきて「???」状態がしばらく続きました(´;ω;｀)

今回はその解決方法を記載していくので興味あったらみていってください～

# 実行したコード
``` index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
```

``` App.jsx
import { useState , useEffect } from 'react';
import './App.css';
import axios from "./axios";
import requests from './Requests';

function App() {
  const [largeCategory, setLargeCategory] = useState([]);

  useEffect(() => {
    async function fetchData() {
      const response = await axios.get(requests.fetchSmallCategory);
      setLargeCategory(response.data.result.small);
      console.log(response.data.result.small);
    }

    fetchData();
  }, []);

  return (
    <>
      <h1>Random Pick App</h1>
      <p>レシピの取得</p>
      <ul>
        {largeCategory.map((menu) => {
          return (
            <li>
              {menu.categoryName}
            </li>
          )
        })}
      </ul>
    </>
  );
}

export default App;
```

``` axios.js
import axios from "axios";

const instance = axios.create({
	baseURL: "https://app.rakuten.co.jp/services/api/Recipe/CategoryList/20170426?format=json",
});

export default instance;
```

``` Requests.js
const API_KEY = "[API_KEY]";

const requests = {
fetchLargeCategory: `/&categoryType=large&applicationId=${API_KEY}`,
fetchMediumCategory: `/&categoryType=medium&applicationId=${API_KEY}`,
fetchSmallCategory: `/&categoryType=small&applicationId=${API_KEY}`,
};

export default requests;

```

# 解決方法
解決方法はとてもシンプルなものでした。
Reactのアプリケーション作成時にデフォルトで記載されているReact.StrictModeを削除すれば解決しました。

``` index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
   // <React.StrictMode> ここを削除
    <App />
   // </React.StrictMode>　ここを削除
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
```

このReact.StrictModeというのを消すことで2回呼ばれるようなことはなくなりました。
じゃあこのReact.StrictModeってなにしてるん？？？

# React.StrictModeとは

以下の内容は公式ドキュメントの内容を一部抜粋したものとなります。

役割：アプリケーションの潜在的な問題点を洗い出すためのツール

``` jsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';

const root = createRoot(document.getElementById('root'));
root.render(
  <StrictMode>
    <App />
  </StrictMode>
);
```
上記の例だと、<App />内はStrictモードの中身のため、良くないところに警告が出されます。

ただ、Strictモードは開発時のみ有効なものであり、ビルドされた本番環境などでは動作しない。

Strictモードでは一部の関数は2回呼び出す。
それは以下のようなものである。
- コンポーネント内の関数(イベントハンドラ内のコードは含まない)
- ***useState, set, useMemo, useReducer関数***
- constructor, render, shouldComponentUpdateのようなクラスコンポーネントメソッド

今回の楽天APIはこの2番目の問題に該当したため、2回呼び出されて、429が返ってきて多っぽいですね。
勉強になった～

# 参考文献
https://legacy.reactjs.org/docs/strict-mode.html

https://marsquai.com/745ca65e-e38b-4a8e-8d59-55421be50f7e/f83dca4c-79db-4adf-b007-697c863b82a5/84dda80d-d8a0-4a1a-a042-66848dc6afe9/