初心者のためのReact Hooks
前回の①はこちら
https://qiita.com/Kojiro-schatten/items/6aa2c3decfe5885231e4
話す内容
ReactHooks(useState, useEffect)を用いて、API連携する際の使い方
早速作ってみる。
https://gyazo.com/a2bff49f7fbfb7b79dad22aabddb5703
上記のGIFのように、クリックするとテキストの状態が変わるAPIを用いたアプリケーションを作ります。
環境構築
以下が必要なファイル群とパッケージです。右のApp.jsxが既にいくつか書き込まれているのは気にしないでください。
(UserList.jsxは作らなくても問題ないです)
axiosに関しては、以下のQiitaが参考になると思います。
https://qiita.com/gcyagyu/items/4d186df2e90c53228951
各ファイルの中身
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;
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;
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;
各ファイルの解説
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を見ていきましょう。
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を見ていきます。
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の参照先は、
の
/posts 100posts
/todos 200todos
を指しているため、それぞれのtitleがクリックイベントによって表示されます。
以上です。
今後、useCallbackとかも扱っていきたいのですが、なかなか筆を取れない。