【GraphQL】フロントエンドで詳細画面へ遷移する
GraphQL

【GraphQL】フロントエンドで詳細画面へ遷移する

作成日:2021年11月27日
更新日:2021年11月28日

前回は、フロントエンドで GraphQL を接続しました。

graphql-client-connect

【GraphQL】フロントエンドでGraphQLを接続する

今回は、GraphQL で接続したデータ一覧から、詳細画面へ遷移します。

コードは、以下の通りです。

フロントエンド:

バックエンド:

まずは、詳細画面を作成しましょう。

pages フォルダに、BookDetail.tsx を作成します。

中身は、MUI のカードを使って作成します。

https://mui.com/components/cards/

また、isReadcreatedAtは、Book.tsx をコピーします。

tsx
import * as React from "react";
import Card from "@mui/material/Card";
import CardContent from "@mui/material/CardContent";
import Typography from "@mui/material/Typography";
export default function BookDetail() {
return (
<Card sx={{ minWidth: 275 }} variant="outlined">
<CardContent>
<Typography sx={{ fontSize: 14 }} color="text.secondary" gutterBottom>
ID:{book.id}
</Typography>
<Typography variant="h5" component="div">
タイトル:{book.title}
</Typography>
<Typography sx={{ mb: 1.5 }} color="text.secondary">
著者:{book.author}
</Typography>
<Typography variant="body2" sx={{ mb: 1.5 }}>
カテゴリ:{book.category.name}
</Typography>
{book.isRead ? (
<Typography variant="body2" sx={{ mb: 1.5 }}>
読了:済
</Typography>
) : (
<Typography variant="body2" sx={{ mb: 1.5 }}>
読了:未
</Typography>
)}
<Typography variant="body2">
作成日:
{`${new Date(Number(book.createdAt))}`
.split(" ")
.splice(1, 3)
.join(" ")}
</Typography>
</CardContent>
</Card>
);
}

App.tsx で、ルート処理をします。

book/:id画面で、bookのデータが表示されないように、path="/book"の前にexactを追加します。

tsx
<Route exact path="/book">
<Dashboard>
<Book />
</Dashboard>
</Route>
<Route path="/book/:id">
<Dashboard>
<BookDetail />
</Dashboard>
</Route>

バックエンドの graphql に移動して、book でデータを取得してみましょう。

image2

こちらの SingleBook の内容をコピーします。

graphql
query SingleBook($bookId: Int!) {
book(id: $bookId) {
id
title
author
category {
name
}
isRead
createdAt
}
}

BookDetail.tsx に戻ります。

gql,と useQuery をインポートします。

tsx
import { gql, useQuery } from "@apollo/client";

gql を作成し、先程コピーした GraphQL を貼り付けます。

tsx
const bookData = gql`
query SingleBook($bookId: Int!) {
book(id: $bookId) {
id
title
author
category {
name
}
isRead
createdAt
}
}
`;

遷移したいデータの id を取得するために、useParamsをインポートします。

tsx
import { useParams } from "react-router-dom";

では、idを取得しましょう。

tsx
const { id } = useParams<{ id?: string | undefined }>();

Book.tsx と同様に、useQueryで、dataerrorloadingを設定します。

tsx
const { data, error, loading } = useQuery(bookData);
if (error) return <div>error page</div>;
if (loading) return <div>Spinner...</div>;
const { book } = data;

bookidと遷移したいデータidを紐づけるため、useQueryのオプションで、variablesを設定します。

指定するのは、bookdatabookIduseParamsidです。

idは string 型なので、number 型へ変換します。

tsx
const { data, error, loading } = useQuery(bookData, {
variables: {
bookId: Number(id),
},
});

では、試しに url で http://localhost:3000/book/1 を入力し、アクセスしてみます。

image3

idが『1』のデータを表示することができました。

Book.tsx で、詳細画面へ遷移するリンクを作成しましょう。

tsx
return (
<React.Fragment>
<Title>読書リスト</Title>
<Table size="small">
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>タイトル</TableCell>
<TableCell>著者</TableCell>
<TableCell>カテゴリ</TableCell>
<TableCell>読了</TableCell>
<TableCell>作成日</TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{books.map((book: TypeBook) => (
<TableRow key={book.id}>
<TableCell>{book.id}</TableCell>
<TableCell>{book.title}</TableCell>
<TableCell>{book.author}</TableCell>
<TableCell>{book.category.name}</TableCell>
{book.isRead ? (
<TableCell></TableCell>
) : (
<TableCell></TableCell>
)}
<TableCell>
{`${new Date(Number(book.createdAt))}`
.split(" ")
.splice(1, 3)
.join(" ")}
</TableCell>
<TableCell>
<Link href={`/book/${book.id}`} underline="hover">
詳細画面
</Link>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</React.Fragment>
);

image4

ID が 2 の『詳細画面』をクリックすると、

image5

正しく画面が遷移しました。

フロントエンドのコード内容は、こちらです。

次回は、フロントエンドで GraphQL のデータを追加します。

graphql-client-create

【GraphQL】フロントエンドでGraphQLのデータを追加する

© 2024あずきぱんウェブスタジオ