[React, API] Fetchしたdataをpropsしてuiに出力

# 概要

今回は、以下の投稿で紹介したAPIのresponceをUIに表示させたいと思います。

>タイトル：Reactでaxiosを使用してAPI Gateway連携済みのLambda(Python)からOpenWeatherMap APIをFetchする
https://qiita.com/ayumu__/items/08838b0ee231948fde40
→この投稿ではconsole.logでコンソールにしか表示できていませんでした。

# 目次
- 完成イメージ
- コード

# 完成イメージ
さっそくですが、完成後のイメージはこんな感じです。現在の東京の天気を取得します。
まずは、何もしてない状態のUIです。まだAPIを叩いてないので、”天気が表示されていません”と出ています。
![スクリーンショット 2023-01-22 17.16.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/4cc6dc48-aa45-c53e-b381-a849b6f0ce16.png)

続いて、”現在の東京の天気を見る”と書かれた緑色のボタンを押すと、真ん中の表示が切り替わります。ボタンを押下することで、APIにfetchしにいきます。そうすることで、現在の東京の天気が取得できていることがわかります。この時の天気は、曇りのようです。
![スクリーンショット 2023-01-22 17.15.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/e80fdd05-3662-cb47-35bd-932cacae1dee.png)

”リセット”と書かれた赤いボタンを押すと、fetch前の表示に切り替わります。

![スクリーンショット 2023-01-22 17.15.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/3dad2398-99db-4476-6cb8-ccea2ae852f4.png)

こんな感じのシンプルなアプリケーションです。
次の章で、コードを見ていきます。

# コード
ここでは、完成イメージに記載したような実装をするためのコードを記載します。（この限りではありません）

一応下にコマンドを書いておきますが、reactのプロジェクトを作るのは済ませておいてください。npm startが失敗する場合は、node.jsの環境構築をしてください。
```terminal:コマンド
> npx create-react-app my-app
> cd my-app
> npm start
```
あとは、以下のソースコード達を改良/追加します。
なお、OpeWetherMap APIのデータをとってきていることに留意してください。とってくるデータによってjsonの要素の名前が変わるので、例えばdata.weatherでは値を引っ張ってこれないです。

```jsx:src/App.js
import './App.css';
import { useState } from "react";
import { ShowApi } from "./ShowApi";


function App() {

    //取得した文字列を格納
    const [fetchData, setFetchData] = useState([]);
    //クリックされたかどうかの状態を保持する
    const [isClick, setIsClick] = useState(false);

    //クリック時に動作
    const handleclick = (e) => {
      //更新を防ぐ
      e.preventDefault();
      
      //Clickされた場合trueをセット
      setIsClick(true);

      //API URL
      const endpointURL = `APIのURLを記載`;

    //APIをたたく（fetch data）
    //非同期を用いる　fetch→responseをjson形式でreturn→dataをfetchDataにセット
    //最後はエラー処理
    fetch(endpointURL)
    .then((res)=>{
      return res.json();
    })
    .then((data)=>{
      setFetchData(data.weather);
    })
    .catch((error) => {
    console.log(error);
    });
    };
    
    //クリック時に動作（リセットボタン）
    const handleclickreset = () => {
      setIsClick(false);
    }
    return (
      <div className="container">
        <h2>API GatewayにデプロイしたAPIを叩きます</h2>
        {/*Enter時に入力された値を関数に渡す */}
      　 <div onClick={handleclick}>
          <input type="button" value="現在の東京の天気を見る"></input>
          {/*三項演算子を用いる。isClickがtrueの場合はprops、falseの場合はpタグがuiに出力*/}
          {/*props：親コンポーネントから子コンポーネントへ値を渡すための仕組み*/}
          {isClick ? (
            <ShowApi fetchData={fetchData} />
          ) : ( 
            <p className="ApiResultShow">天気が表示されていません</p>
          )}
      　</div>
      　{/* リセットボタンを押すことで、isClickにfalseがsetされるので、false時の三項演算子の出力になる */}
      　<div onClick={handleclickreset}>
        　<input className="ResetButton" type="button" value="リセット" ></input>
      　</div>
    　</div>
    );
}

export default App;
```
useStateを使って状態管理を実施し、三項演算子を使ってisClickの状態によって、APIで取得したデータをUIに出力させたりさせなかったりしています。
apiとの通信には、fetchメソッドを使いました。前の記事ではaxiosというパッケージを使っています。AWSのec2とかamplifyにアプリをホスティングした場合、fetchはimportしないとエラー出ますが、ローカルでは平気です。
<br>

続いて、以下のファイルはデフォルトでインストールされないので、srcフォルダ内に作成します。
```jsx:src/ShowApi.jsx
import React from 'react'

//親コンポーネントからの値を受け取る
export const ShowApi = ({fetchData}) => {
  return (
    <div>
      {/*map関数を使って、受け取ったデータを格納する(リストのように表示してける)*/}
          {fetchData.map((data) => (
            //fetchした値をuiに出力させる
            //map関数を実行するとリスト項目には key を与えるべきだとエラーがでる。
            //そのため、配列内の項目に安定した識別性を与えるため、それぞれの項目にkeyを指定する。 
            <div  key={data.id} className="ApiResultShow" >
              現在の東京の天気：{data.main}
            </div>
          ))}
    </div>
  )
}
```
propsによって、親コンポートでfetchした値を子コンポートに渡しています。
<br>

CSSは以下のようになっています。

```css:App.css
.container {
  width: 100%;
  height: 100vh;
  padding: 36px 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.container h2 {
  margin-bottom: 2.5rem;
}

.container input {
  min-width: 360px;
  padding: 5px 12px;
  margin-bottom: 36px;
  border-radius: 8px;
  background-color: #98fb98;
}

.container div p.ApiResultShow {
  text-align: center;
  margin-bottom: 2.5rem;
}

.container div.ApiResultShow {
  text-align: center;
  margin-bottom: 2.5rem;
}

.container input.ResetButton {
  background-color: #fa8072;
  position: center fixed;
}

```

これで完了です、ファイルを保存して、npm startしてみましょう。完成イメージのように作れていれば完成です。

<br>
また、vsCodeで開発をする場合、以下の拡張機能を入れておくと、ショートカットが色々使えるので便利です。（やらなくてもokです、本記事記載のコード通りに書けば動きます)。これを入れておくと、例えば、rafcと新規に作成したファイルで打ち込むとショートカットが表示されるので、それを使用すると、新規に追加したファイルのパスを自動で通してくれたりします。）

![スクリーンショット 2023-01-22 17.34.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/430c3c49-74b5-c059-2eb9-445d91aad532.png)

# おわりに
- 今回は、ReactでAPI Callして、そのレスポンス内の任意のデータをuiに出力させる方法を記載しました。
- CSSが難しいと感じる今日この頃なので、勉強していきます。
- それでは。