概述
是时候处理 UI,让我们的曲目详情页面动起来了。
在此课程中,我们将
- 创建
track
页面 - 将新
GET_TRACK
操作导入到前端 - 调用
useQuery
钩子,传递一个trackId
变量
访问曲目页面
我们的应用已通过路由逻辑设置,可以显示特定曲目的页面。我们来尝试一下。
运行 npm start
。
这应在浏览器中打开到 http://127.0.0.1:3000/
或 localhost:3000以显示主页。
然后,我们导航到: localhost:3000/track/c_0。我们仍应看到一个空 Catstronauts 布局,但这告诉我们该路由正在工作。我们将开始用从 查询中检索到的数据来填充它。
📄 建设曲目页面
让我们给这个曲目页面一些东西来显示!
跳转到 src/pages
文件夹,并打开 track.tsx
。
此文件输出名为 Track
的基本组件,但目前仅有很少的功能。
import React from "react";import { Layout, QueryResult } from "../components";const Track = () => {return <Layout></Layout>;};export default Track;
处理导入
让我们导入一些用于构建此页面的软件包。
首先,我们将从 __generated__
文件夹导入 gql
,然后从 @apollo/client
导入 useQuery
。接下来,为了确定 将 显示其详细信息的磁道,我们需要访问路由中传递的 trackId
。为此,我们使用 useParams
,它来自 react-router-dom
。
import { gql } from "../__generated__";import { useQuery } from "@apollo/client";import { useParams } from "react-router-dom";
现在,让我们跳到 Track
组件中。在花括号内,我们将对通过 useParams
函数返回的对象解构出 trackId
。如果没有传递任何 trackId
,我们将其设置为一个空字符串。
const Track = () => {const { trackId = "" } = useParams();return <Layout></Layout>;};
💻 设置我们客户端的查询
是时候构建我们的磁道 查询 了。我们将使用全大写字母称其为 GET_TRACK
并使用 __generated__
文件夹中的 gql
函数。
export const GET_TRACK = gql(`# our query goes here`);
现在,我们可以手动构建我们的 查询,也可以从 Sandbox 中获取已经完成的查询,在 操作 面板中复制查询,然后将其粘贴在 gql
标签中的反引号之间,即 GET_TRACK
变量。
query GetTrack($trackId: ID!) {track(id: $trackId) {idtitleauthor {idnamephoto}thumbnaillengthmodulesCountdescriptionnumberOfViewsmodules {idtitlelengthcontentvideoUrl}}}
重新运行代码生成
我们已为前端编写新的 GraphQL 操作,为了保持 TypeScript 代码准确,我们需要在根文件夹再次运行代码生成命令!此操作将重新评估前端代码中使用的操作,并自动生成保持代码一致且无 bug 所需的类型。每当我们更新 GraphQL 操作或添加或删除操作时,我们都应确保重新生成我们的类型!
npm run generate
我们应看到一些关于我们的代码生成运行成功的输出,然后我们就可以继续进行!
🪝 设置 useQuery
hook
正如您从以前的课程中所知,我们使用 Apollo 客户端的 useQuery hook 从我们的客户端向 GraphQL 服务器发出调用。
我们将在此 Track
组件中使用此 hook。在 return
行之前,我们可以声明我们从 useQuery
hook 接收到的通常的 loading
、error
和 data
对象。
const { loading, error, data } = useQuery();
我们传递 GET_TRACK
查询 作为 hook 的第一个 参数,现在与我们之前的查询相比最大的区别是添加了第二个参数: options
对象。
此对象将持有 variables
键,注 variables,带 “S” 因为它可以有多个 variables。此 variables
键将对象作为值,我们将在其中传递我们的 trackId
。
const { loading, error, data } = useQuery(GET_TRACK, {variables: { trackId },});
QueryResult
组件
与主页类似,我们将使用预先构建的 QueryResult
组件来处理任何错误并正确显示加载状态。
在 Layout
组件的打开和关闭标签内添加 QueryResult
组件:
<Layout><QueryResult error={error} loading={loading} data={data}>{/* this is where our component displaying the data will go */}</QueryResult></Layout>
当 查询 加载完成且没有错误时, QueryResult
组件将呈现其子项,将它们所需的数据传递给它们。
TrackDetail
组件
我们提供了便捷的 TrackDetail
组件,随时可以使用来显示该数据。它位于 src/components
文件夹中,所以如果你有兴趣,可以随时花一分钟查看它,了解 UI 元素如何组织的。
让我们在 track.tsx
文件的顶部导入 TrackDetail
组件。
import TrackDetail from "../components/track-detail";
现在在 QueryResult
内部,我们可以渲染 TrackDetail
组件并设置 track
属性为 data?.track
,这里使用可选链,因为数据在 查询 加载完成之前不可用。
<TrackDetail track={data?.track} />
我们已经为轨道页准备好了!下面是经过我们所有更改之后 track.tsx
文件的应有样子:
import React from "react";import { gql } from "../__generated__";import { useQuery } from "@apollo/client";import { Layout, QueryResult } from "../components";import { useParams } from "react-router-dom";import TrackDetail from "../components/track-detail";export const GET_TRACK = gql(`query GetTrack($trackId: ID!) {track(id: $trackId) {idtitleauthor {idnamephoto}thumbnaillengthmodulesCountnumberOfViewsmodules {idtitlelength}description}}`);const Track = () => {const { trackId = "" } = useParams();const { loading, error, data } = useQuery(GET_TRACK, {variables: { trackId },});return (<Layout><QueryResult error={error} loading={loading} data={data}><TrackDetail track={data?.track} /></QueryResult></Layout>);};export default Track;
💻 检查浏览器!
如果我们导航回浏览器到 localhost:3000/track/c_0,我们应该看到该轨道页以及显示的所有详细信息!我们可以看到我们太空小猫的精美大缩略图、标题、轨道详细信息、作者、模块详细信息和描述!如果我们更改 URL 以显示不同的轨道 ID,例如 c_1
或 c_2
,该页面会更新为正确的数据。
太棒了,我们走上了正确的 轨道! 🥁
让我们通过 localhost:3000 跳回至主页。
我们仍然在轨道卡片网格上显示了主页,因此我们当时并未破坏任何内容。现在,如果我们单击卡片,我们将转到该轨道的页面。
太棒了!我们可以返回主页,单击其他一些轨道,并查看其数据是否也可以正确加载。
😲 缓存后台
现在,你可能会注意到,如果我们单击以前已单击过的轨道,则该页面会极速弹出!与单击我们之前从未单击过的轨道相比,我们可以在页面上看到任何详细信息之前看到加载图标在旋转。
这种快速加载行为要归功于 Apollo Client!
第一次向 GraphQL 服务器发送 查询 时, Apollo Client 会将结果存储在缓存中。下次我们尝试发送相同的查询时(例如,再次导航到同一页面),它将从缓存加载结果,而不是通过网络发送不必要的调用。
非常方便! Apollo Client 在我们为之前的一节课中设置的 InMemoryCache
中处理这种缓存行为。
练习
将此框中的项目拖到上面的空白处
graphql
useQuery
useState
gql
useApolloClient
使用 useQuery
钩子将 GET_SPACECAT
查询发送至服务器。它将 spaceCatId
作为变量。从钩子的返回对象中解构 loading
、error
和 data
属性。
useQuery
钩子useQuery
钩子的参数,在一个选项对象内部。将此框中的项目拖到上面的空白处
isComplete
data
error
first
loading
variables
arguments
second
results
主要结论
-
useQuery
钩子接收一个可选的第二个 参数,一个options
对象,在其中我们可以定义variables
对象。 - Apollo 客户端 将 查询 结果存储在它的缓存中,这允许更快速的内容加载。
接下来
我们的应用设置到目前为止 查询 数据,但如何更改数据呢?为了为我们的应用程序带来一些交互性,我们将深入了解此课程的最终主题: GraphQL 突变。
分享您对此课程的问题和评论
本课程目前处于
你需要使用 GitHub 账户才能在下面发帖。还没有 GitHub 账户? 在我们的 Odyssey 论坛发帖。