2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ReactのHooksの使い方② -useEffect-

Last updated at Posted at 2020-03-15

初心者のためのReact Hooks

前回の①はこちら
https://qiita.com/Kojiro-schatten/items/6aa2c3decfe5885231e4

話す内容

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

早速作ってみる。

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

環境構築

以下が必要なファイル群とパッケージです。右のApp.jsxが既にいくつか書き込まれているのは気にしないでください。
2020-03-15_1927.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の参照先は、
スクリーンショット 2020-03-16 1.12.31.png

/posts 100posts
/todos 200todos
を指しているため、それぞれのtitleがクリックイベントによって表示されます。

以上です。

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

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?