ReactのHooksの使い方② -useEffect-

## 初心者のためのReact Hooks
前回の①はこちら
https://qiita.com/Kojiro-schatten/items/6aa2c3decfe5885231e4

## 話す内容
ReactHooks(useState, useEffect)を用いて、API連携する際の使い方

## 早速作ってみる。
https://gyazo.com/a2bff49f7fbfb7b79dad22aabddb5703
上記のGIFのように、クリックするとテキストの状態が変わるAPIを用いたアプリケーションを作ります。

## 環境構築
以下が必要なファイル群とパッケージです。右のApp.jsxが既にいくつか書き込まれているのは気にしないでください。
<img width="673" alt="2020-03-15_1927.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439329/758dc1fe-29b9-7184-db35-c4433475d39e.png">
**(UserList.jsxは作らなくても問題ないです)**

axiosに関しては、以下のQiitaが参考になると思います。
https://qiita.com/gcyagyu/items/4d186df2e90c53228951

## 各ファイルの中身

```App.js
import React, { useState } from "react";
import ResourceList from "./ResourceList";

const App = () => {
  const [resource, setResource] = useState("posts");

  return (
    <div>

      <div>
        <button onClick={() => setResource("posts")}>Posts</button>
        <button onClick={() => setResource("todos")}>Todos</button>
      </div>
      <ResourceList resource={resource} />
    </div>
  );
};

export default App;
```

```ResourceList.jsx
import React from "react";
import useResources from "./useResources";

const ResourceList = ({ resource }) => {
  const resources = useResources(resource);

  return (
    <ul>
      {resources.map(record => (
        <li key={record.id}>{record.title}</li>
      ))}
    </ul>
  );
};

export default ResourceList;
```

```useResources.jsx
import { useState, useEffect } from "react";
import axios from "axios";

const useResources = resource => {
  const [resources, setResources] = useState([]);

  useEffect(() => {
    (async resource => {
      const response = await axios.get(
        `https://jsonplaceholder.typicode.com/${resource}`
      );
      setResources(response.data);
    })(resource);
  }, [resource]);
  return resources;
  // 即時関数の形
};

export default useResources;

```

## 各ファイルの解説
```App.js
import React, { useState } from "react";
import ResourceList from "./ResourceList";
import UserList from "./UserList";

const App = () => {
  const [resource, setResource] = useState("posts");

  return (
    <div>
      <UserList />
      <div>
        <button onClick={() => setResource("posts")}>Posts</button>
        <button onClick={() => setResource("todos")}>Todos</button>
      </div>
      <ResourceList resource={resource} />
    </div>
  );
};

export default App;
```


まず、App.jsです。
importでは、ResourceListとUserListをimportしています。App関数の最初に

```
const [resource, setResource] = useState("posts");
```

とありますね。第一引数は、

```
<ResourceList resource={resource} />
```
の部分で使われています。第二引数のsetResourceは、buttonのonClickアクションで引き起こされることから、
**PostsボタンかTodosボタンを押した場合、setResource()アクションが発火し、Postsならposts、Todosならtodosという引数を呼び出して、その結果をresourceのテキストを変えるということになります。**

では、次に、ResourceList.jsxを見ていきましょう。

```ResourceList.jsx
import React from "react";
import useResources from "./useResources";

const ResourceList = ({ resource }) => {
  const resources = useResources(resource);

  return (
    <ul>
      {resources.map(record => (
        <li key={record.id}>{record.title}</li>
      ))}
    </ul>
  );
};

export default ResourceList;
```
ResourceListと呼ばれる関数を作り、引数にresourceをセットします。今回、returnの中身でmapメソッドを使用していますね。mapメソッドとは、**与えられた関数を配列のすべての要素に対して呼び出し、その結果からなる新しい配列を生成します。**
(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
今回、keyがrecord.idになっています。表示されるのは、record.titleですね。recordの部分は、どんな名前でも構いません。

次に、useResources.jsxを見ていきます。

```useResources.jsx
import { useState, useEffect } from "react";
import axios from "axios";

const useResources = resource => {
  const [resources, setResources] = useState([]);

  useEffect(() => {
    (async resource => {
      const response = await axios.get(
        `https://jsonplaceholder.typicode.com/${resource}`
      );
      setResources(response.data);
    })(resource);
  }, [resource]);
  return resources;
  // 即時関数の形
};

export default useResources;

```
ResourceListと同様に、resourceを引数としたuseResources関数があります。
ここで、初めてuseEffectが出てきました。useEffectは、第一引数にコールバック関数を入れて、第二引数にその関数に依存する値の配列を入れられます。依存する値が変更される度にcallbackが実行されます。async awaitを使っていますが、今回は割愛します。
さて、第一引数が

```
() => {
    (async resource => {
      const response = await axios.get(
        `https://jsonplaceholder.typicode.com/${resource}`
      );
      setResources(response.data);
    })(resource);
  },
```
中身のaxiosに関してですが、第一引数にはエンドポイント、第二引数に渡したいパラメータを指定します。今回axios.getとしており、jsonplaceholderからresource部分を取得していることが分かります。setResourcesの部分は、引数をresponse.dataとしており、最終的に

```
const [resources, setResources] = useState([])
```
のresourcesの値を更新しています。
今回、App.jsで

```
<div>
   <button onClick={() => setResource('posts')} >Posts</button>
　　<button onClick={() => setResource('todos')} >Todos</button>
</div>
<ResourceList resource={resource} />
```

としているため、
setResourceには、postsの内容とtodosの内容が入っていますね。この二つを、onClickメソッドによって、resource={resource}部分の表示を変更させることができます。また、postsとtodosの参照先は、
<img width="918" alt="スクリーンショット 2020-03-16 1.12.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439329/3e112142-c860-bf63-83db-e63a65c3a48d.png">
の
/posts 100posts
/todos 200todos
を指しているため、それぞれのtitleがクリックイベントによって表示されます。

以上です。

今後、useCallbackとかも扱っていきたいのですが、なかなか筆を取れない。