# バックエンドからデータを取得

先ほどの`useEffect`を利用して、バックエンドからデータを取得する方法を説明します。今回バックエンドは学習用に用意された以下のサイトを利用します。

{% embed url="<https://jsonplaceholder.typicode.com/>" %}

バックエンドのAPIからデータを取得するために、`axios`というライブラリをインストールします。

```bash
npm install axios
```

`axios`をインストールしたら、JsonPlaceholderの [https://jsonplaceholder.typicode.com/post](https://jsonplaceholder.typicode.com/posts) というURLを叩いて投稿一覧を取得しましょう。`useEffect`内にて、`axios.get(url)`とすることで、データを取得することができます。`axios.get(url)`にて返却する型ですが、`Promise型`という型で、**非同期処理**の操作が完了したときに結果を返却するものです。

まず**非同期処理**の説明の前に**同期処理**の説明をします。**同期処理**とは、上から順に処理が行われることで、以下コードがあった場合1,2,3と順番にコンソールに出力されるかと思います。

```javascript
console.log(1)
console.log(2)
console.log(3)
```

一方で**非同期処理**はその処理が完了するのを待たずに次の処理が実行されます。その時点で非同期処理をコンソールに出力しようとすると、`pending`というPromise型のオブジェクトが返却されます。

```
console.log(1)
console.log(2)
非同期処理
console.log(3)
```

その`Promise`型の処理結果を受け取るためには、`.then`と繋げることで処理結果を受け取ることができます。ですので、`axios.get(url).then((res) => ...)`と記述することで、バックエンドからデータを取得することができます。まずは取得した結果をコンソールに出力してみましょう。

<pre class="language-tsx" data-title="PostList.tsx◎"><code class="lang-tsx"><strong>import axios from "axios";
</strong>...
<strong>  useEffect(() => {
</strong><strong>    axios.get("https://jsonplaceholder.typicode.com/posts").then((res) => {
</strong><strong>      console.log(res);
</strong><strong>    });
</strong>  }, [userId]);
...
</code></pre>

以下のようなオブジェクトが出力されるかと思います。投稿一覧は`data`プロパティに格納されています。

<figure><img src="https://1869761657-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcUBbYqol4PMzZJggiMqV%2Fuploads%2FuiE6JNupBKnPzwfWA76N%2F202312080905.png?alt=media&#x26;token=e47e8204-4fb4-419b-9cd6-2b1f77a8fd26" alt=""><figcaption></figcaption></figure>

こちらのデータを`postList`というstateを作り、取得した投稿一覧を格納しましょう。

そして、`Post`型を作り、`postList`の型を`Post`型の配列にしましょう。

また、`res.data`の型を`axios.get<Post[]>(...)`と宣言することができます。

<pre class="language-tsx" data-title="PostList.tsx◎"><code class="lang-tsx">...

<strong>type Post = {
</strong><strong>  id: number;
</strong><strong>  userId: number;
</strong><strong>  title: string;
</strong><strong>  body: string;
</strong><strong>};
</strong>
export const PostList = () => {
<strong>  const [postList, setPostList] = useState&#x3C;Post[]>([]);
</strong>  const [userId, setUserId] = useState(1);

  useEffect(() => {
    axios.get&#x3C;Post[]>("https://jsonplaceholder.typicode.com/posts").then((res) => {
<strong>      setPostList(res.data as Post[]);
</strong>    });
  }, [userId]);
...
</code></pre>

格納した投稿一覧をUserListを作成したときのようにtableタグにて表示するようにしましょう。

<pre class="language-tsx" data-title="PostList.tsx◎"><code class="lang-tsx">...
  return (
    &#x3C;div>
      &#x3C;h2>PostsList&#x3C;/h2>
      &#x3C;div>
        &#x3C;p>userID: {userId}&#x3C;/p>
        &#x3C;input
          type="number"
          value={userId}
          onChange={(e) => setUserId(Number(e.target.value))}
        />
      &#x3C;/div>
<strong>      &#x3C;table className="table">
</strong><strong>        &#x3C;thead>
</strong><strong>          &#x3C;tr>
</strong><strong>            &#x3C;th scope="col">id&#x3C;/th>
</strong><strong>            &#x3C;th scope="col">ユーザーid&#x3C;/th>
</strong><strong>            &#x3C;th scope="col">タイトル&#x3C;/th>
</strong><strong>            &#x3C;th scope="col">内容&#x3C;/th>
</strong><strong>          &#x3C;/tr>
</strong><strong>        &#x3C;/thead>
</strong><strong>        &#x3C;tbody>
</strong><strong>          {postList.map((post) => (
</strong><strong>            &#x3C;tr key={post.id}>
</strong><strong>              &#x3C;td>{post.id}&#x3C;/td>
</strong><strong>              &#x3C;td>{post.userId}&#x3C;/td>
</strong><strong>              &#x3C;td>{post.title}&#x3C;/td>
</strong><strong>              &#x3C;td>{post.body}&#x3C;/td>
</strong><strong>            &#x3C;/tr>
</strong><strong>          ))}
</strong><strong>        &#x3C;/tbody>
</strong><strong>      &#x3C;/table>
</strong>    &#x3C;/div>
  );
...
</code></pre>

これで投稿一覧が表示されました。

<figure><img src="https://1869761657-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcUBbYqol4PMzZJggiMqV%2Fuploads%2FU6EXu8Kbmaxx45fazIbW%2F202312080923.png?alt=media&#x26;token=0f2ab193-5175-4cd4-8f7c-2b1734a42768" alt=""><figcaption></figcaption></figure>

次に投稿一覧から、特定のユーザーIDのもののみを表示するようにしましょう。先ほど、useEffectにて`userId`を監視するようにしましたが、バックエンドのAPIを叩く際に`userId`などのパラメータを渡して、バックエンド側でフィルターをかけるような実装が多々あります。そういった場合は、`userId`を監視するようにするのですが、今回はフロントエンド側でフィルターをかけるようにしますので、`useEffect`の監視する値を空としましょう。

<pre class="language-tsx" data-title="PostList.tsx◎"><code class="lang-tsx">...
  useEffect(() => {
    axios.get&#x3C;Post[]>("https://jsonplaceholder.typicode.com/posts").then((res) => {
      setPostList(res.data as Post[]);
    });
<strong>  }, []);
</strong>...
</code></pre>

そして、`postList`の`map`する前に`userId`にて`filter`しましょう

<pre class="language-tsx" data-title="PostList.tsx◎"><code class="lang-tsx">...
<strong>          {postList
</strong><strong>            .filter((post) => post.userId === userId)
</strong>            .map((post) => (
              &#x3C;tr key={post.id}>
                &#x3C;td>{post.id}&#x3C;/td>
                &#x3C;td>{post.userId}&#x3C;/td>
                &#x3C;td>{post.title}&#x3C;/td>
                &#x3C;td>{post.body}&#x3C;/td>
              &#x3C;/tr>
            ))}
...
</code></pre>

上記にて、userIdを変更することで投稿内容を特定のユーザーのみにフィルターすることができます。

<figure><img src="https://1869761657-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FcUBbYqol4PMzZJggiMqV%2Fuploads%2FlSDUcBg0Yngvan0ZGbbN%2F202312081106.png?alt=media&#x26;token=744beb8b-9ad2-4782-ba4f-14bf8a75ccc1" alt=""><figcaption></figcaption></figure>
