概述
在Explorer中构建变异是开始的绝佳去处,但现在我们需要将相同的功能带入我们的应用程序。让我们回到代码并使用一个新挂钩发出我们的变异!
在本次课程中,我们将
- 了解
useMutation
挂钩 - 在访问页面时增加对某个曲目的观看次数
- 讨论Apollo Client缓存
💻 客户端的变异
让我们重新审视我们的目标:我们希望在从主页导航到曲目页面之前更新观看次数。此导航正在我们的TrackCard
组件中进行。
在src/containers
文件夹中,我们打开track-card.tsx
文件。
首先,让我们通过导入@apollo/client
包开始。我们需要useMutation
钩子,将我们的突变发送到我们的服务器。我们还需要在我们的__generated__
文件夹中导入gql
,因为我们将在我们的突变中使用这个相同的函数。
import { useMutation } from "@apollo/client";import { gql } from "../__generated__";
接下来,让我们创建一个新的变量,用于保存我们的突变,名为INCREMENT_TRACK_VIEWS
,并将其设置为gql
函数调用,添加反引号 (`
)。在反引号内,我们将粘贴突变,我们之前在 Studio 中构建它,并添加一个注释来解释这个突变的用途。
/*** Mutation to increment a track's number of views*/const INCREMENT_TRACK_VIEWS = gql(`mutation IncrementTrackViews($incrementTrackViewsId: ID!) {incrementTrackViews(id: $incrementTrackViewsId) {codesuccessmessagetrack {idnumberOfViews}}}`);
🎣 useMutation
钩子
因为这是一个突变而不是查询,所以我们不会使用我们熟悉的useQuery
钩子。相反,我们将切换到useMutation
钩子。
在TrackCard
组件中,我们将通过调用钩子开始。它需要第一个参数作为我们之前设置的突变,INCREMENT_TRACK_VIEWS
。
第二个参数是带有 options
键的 variables
对象。在这里,我们将添加 incrementTrackViewsId
变量并将其设置为将要导航到的音轨的 id
。此 id
已经从顶部的 track
prop 中为我们解构。
useMutation(INCREMENT_TRACK_VIEWS, {variables: { incrementTrackViewsId: id },});
现在,这里有一个曲折:与 useQuery
不同,调用 useMutation
实际上不会自动执行 mutation!
相反, useMutation
钩子会返回一个包含两个元素的数组,我们开始在此处解构该数组。
const [incrementTrackViews] = useMutation(INCREMENT_TRACK_VIEWS, {variables: { incrementTrackViewsId: id },});
第一个元素是稍后我们将用来实际运行 mutate 函数 mutation的。我们将称之为 incrementTrackViews
。第二个元素是一个带有有关 mutation 的信息的对象: loading
、 error
和 data
。此组件不需要它,因此我们不必提取它。
我们添加了一个新 operation,因此需要为前端重新生成我们的类型。在根目录中运行以下命令。
npm run generate
👆🏽设置 onClick
我们什么时候想要运行我们的 mutate 函数?当用户点击卡片时!
让我们将 onClick
prop 添加到 CardContainer
组件并配置它以调用我们的 mutate 函数 incrementTrackViews
。
<CardContainerto={`/track/${id}`}onClick={() => incrementTrackViews()}>
1️⃣ 另一件事……
最后一件事——让我们添加一个控制台日志,以便在 mutation 完成时检查其响应。
为此,让我们返回到我们设置 useMutation
钩子并向 options
对象添加另一个属性的地方。 onCompleted
属性是当 mutation 成功完成时运行的回调函数,并且可以访问返回的响应。 我们会将响应记录到浏览器控制台中。
const [incrementTrackViews] = useMutation(INCREMENT_TRACK_VIEWS, {variables: { incrementTrackViewsId: id },// to observe what the mutation response returnsonCompleted: (data) => {console.log(data);},});
我们的客户端应用准备将这个 mutation 发送到服务器!让我们在上节课中看看我们旅程的结果。
👀 看到结果
让我们看看我们的应用程序现在是什么样的。
确认您的应用程序仍在运行,或者通过打开终端并运行 npm start
重新启动它。 然后,我们将打开 https://127.0.0.1:3000 在浏览器中。
我们在主页上看到所有曲目。现在,让我们点击第二首曲目,我们应该在这里看到观看次数。
如果我们返回主页并再次点击该曲目,我们现在可以看到观看次数增加了!太棒了!
注意:请记住,您的观看次数可能与视频不同!要检查您的 mutation 是否成功,请打开浏览器的开发工具并找到 console.log
我们之前设置的 message。
现在,如果您有敏锐的眼睛(或缓慢的互联网连接 🐌 ),您可能会在这里注意到一些东西。事实上,让我们打开开发人员工具控制台,并使用视频魔法减慢速度,以便我们可以确切地看到正在发生什么。
您看到了吗?页面立即加载了所有曲目数据,然后在经过短暂的延迟后,观看次数从 2
更改为 3
!我们会看到我们之前设置的控制台日志在这里弹出。这意味着我们的 mutation 是在页面加载后完成的。那么,我们如何在之前没有任何错误的情况下在页面上看到所有内容?虽然我们在上一页上运行了 mutation,但它又是如何在这个页面上更新的呢?
🗳️ Apollo 客户端缓存
这归功于 Apollo 客户端 缓存!
当我们使用 useQuery
钩子和 变量 时,我们看到了如果之前已经点击过某个音轨,音轨会在页面上多么快显示出来。这是因为它从缓存中加载,这意味着我们没有向我们的 GraphQL API 发送不必要的查询。
同样,当我们的 突变 发送到我们的 API 时,我们仍然从缓存中加载页面。一旦成功返回,我们就能为 numberOfViewsnumberOfViews 获取更新的值。Apollo 客户端 在幕后查看此音轨的 id
,在缓存中搜索它,并更新它的 numberOfViews
字段。当缓存更新时,UI 也会更新。感谢 Apollo 客户端!
实践
loading
、error
和 将该框中的项目拖拽至上方的空白处
options
array
useQuery
values
useGqlQuery
arguments
variables
integer
useMutation
GraphQL 操作
mutate 函数
data
useQuery
和 useMutation
钩子之间的区别?使用 useMutation 钩子向服务器发送 ASSIGN_SPACESHIP_MUTATION
变异。它需要两个变量: spaceshipId
和 missionId
。解构 mutate 函数(称之为 assignSpaceship
),以及钩子返回数组中的 loading
、error
和 data
属性。
要点
-
useMutation
钩子接受一个 mutation operation 作为其第一个参数,第二个参数则是options
对象,对象中包含一个variables
键。 - useMutation
钩子不会自动执行突变;相反,它会返回一个数组。此数组包含一个变异函数,我们可以随时调用,以及包含
loading
、error
和data
属性的对象。 - Apollo Client缓存加载已从缓存中获取的数据,从而缩短页面的加载时间并减少不必要的网络调用!
🎉我们完成了!
非常感谢您与我们一起参加客户端GraphQL与 React & Apollo。现在,我们有了可供有抱负的宇航猫使用来探索宇宙的工作应用程序,并且我们可以通过观看次数来了解某一轨道的受欢迎程度。
我们很想知道您的反馈。让我们知道您喜欢什么,不喜欢什么,以及您希望接下来在奥德赛上看到什么!
分享您对本课程的问题和评论
此课程当前处于
您需要一个 GitHub 帐户才能在下方发帖。没有吗? 转而发布在我们的奥德赛论坛中。