前回は、React Queryでキャッシュを設定します。

今回は、React QueryでAPIから特定のデータを取得します。

JSON Placeholder(https://jsonplaceholder.typicode.com/)からPostデータを取得しました。

import React from "react";
import { useQuery } from "react-query";

interface Post {
  userId: string,
  id: string,
  title: string,
  body: string,
}

export default function Page() {
  const { isLoading, isError, data } = useQuery(
    "post",
    () =>
      fetch("https://jsonplaceholder.typicode.com/posts/").then((res) =>
        res.json()
      )
  );

  if (isLoading) return <>Loading...</>;

  if (isError) return <>Error</>;

  return (
    <>
      <ul>
        {data.map((post: Post) => (
          <li key={post.id}>
            <p style={{fontWeight:"bold"}}>{post.title}</p>
          </li>
        ))}
      </ul>
    </>
  );
}

image2

特定のタイトルをクリックすると、タイトルのPost詳細を画面上に表示するようにします。

まずは、Detailコンポーネントを作成します。

import React from "react";
import { useQuery } from "react-query";

export default function Detail({postId}:{postId:string}) {
  const { isLoading, isError, data } = useQuery("post", () =>
    fetch(`https://jsonplaceholder.typicode.com/posts/`).then((res) =>
      res.json()
    )
  );
 
  if (isLoading) return <>Loading...</>;

  if (isError) return <>Error</>;

  return (
    <>
      <h1>{data.title}</h1>
      <p>{data.body}</p>
    </>
  );
}

useQueryでクエリキーを使うことで、特定のデータを取得することができます。

useQueryの後のクエリ名を『[]』で囲みます。

クエリ名の後に『,』を追加し、postIdを指定します。

const { isLoading, isError, data } = useQuery(["post", postId], () =>
  fetch(`https://jsonplaceholder.typicode.com/posts/`).then((res) =>
    res.json()
  )
);

JSONPlaceholderでは、posts/の後にpostのidを指定することで、詳細データを取得することができます。 URLの後に、${postID}を追加しましょう。

const { isLoading, isError, data } = useQuery(["post", postId], () =>
  fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`).then((res) =>
    res.json()
  )
);

Detailコンポーネントの作成が完了したので、一覧画面のコンポーネントに、Detailコンポーネントを追加します。

return (
  <>
    <Detail postId={postId}/>
    <ul>
      {data.map((post: Post) => (
        <li key={post.id}>
          <p style={{fontWeight:"bold"}}>{post.title}</p>
        </li>
      ))}
    </ul>
  </>
);

タイトルをクリックするとpostのidを受け渡せるように、useStateonClickで状態管理します。

const [postId, setPostId] = useState("");
<li key={post.id} onClick={() => setPostId(post.id)}>
  <p style={{fontWeight:"bold"}}>{post.title}</p>
</li>

一通り完成したので、確認してみましょう。

image3

タイトルをクリックすると、

image4

タイトルの内容が表示されました。

React Queryを見てみます。

image5

postのid1の内容を取得することができています。

ちなみに他のタイトルをクリックすると、

image6

他のタイトル内容がアクティブになり、内容を表示することができました。

ブログ一覧