接上篇 —— Apollo 入门引导(七):通过查询获取数据 —— 继续翻译 Apollo 的官网入门引导。
学习如何使用 useMutation hook 修改数据。
Apollo 入门引导 - 目录:
完成时间:10 分钟
前一节已经向 React 应用添加了多个查询,接下来添加一个变更(mutation)。过程与查询相似,但有一些重要区别。
提醒一下,变更是 GraphQL 操作,可以修改后端数据(与查询不同)。我们服务的 schema 支持以下变更:
1 | # 不需要复制 |
将从实现登录功能开始。请注意,此变更接受单个变量 email
。
支持用户登录
注意:为简单起见,我们的示例应用未使用基于密码的身份验证来实现真正的用户帐户。而是用户通过提交其 email 地址并从服务接收相应的 session token 来不安全地“登录”。
定义变更
首先,导航到src/pages/login.tsx
并将其内容替换为以下内容:
1 | import React from 'react'; // preserve-line |
LOGIN_USER
定义看起来像上一节中的查询,只是它用 mutation
代替了 query
。在来自 login
的响应中收到服务生成的 token
,代表了用户的 session。
应用 useMutation
hook
将使用 Apollo 客户端的 useMutation
React Hook来执行LOGIN_USER
变更。与 useQuery
一样,hook 的结果提供的属性可在整个变更的执行过程中填充和呈现组件。
与 useQuery
不同的是,useMutation
不会在其组件呈现后立即执行其操作。该 hook 返回一个mutate function,可以在需要时(例如用户提交表单时)调用该函数以执行该变更。
将以下内容添加到 login.tsx
的底部:
1 | export default function Login() { |
useMutation
的结果元数据(login
)中的第一个对象,就是执行变更的 mutate 函数。将此函数传给LoginForm
组件。- 元数据中的第二个对象与
useQuery
返回的结果对象相似,包括操作的loading
和error
状态以及操作的结果data
。
现在,每当用户提交登录表单时,就会调用 login
变更。用户的 token
存储在内存缓存中,但是我们希望该 token
可在同一浏览器中多次访问时使用。接下来让解决这个问题。
保留用户 token
在对 useMutation
的调用的参数中中,可以包含一个 onCompleted
回调函数。这样一来便可以与变更的结果数据进行交互。将使用此回调来保留用户的 token
。
修改 login.tsx
中的 useMutation
调用以匹配以下内容:
1 | const [login, { loading, error }] = useMutation< |
onCompleted
回调函数将用户的唯一 ID 和 session token 存储在 localStorage
中,因此可以在用户下次访问应用时将这些值加载到内存缓存中。将在下一章中添加该功能。
向所有请求添加 Authorization
头
客户端应该将用户的 token 添加到每个发送到服务的 GraphQL 操作中。这使服务可以验证用户是否有权执行他们要尝试执行的操作。
在 index.tsx
中,修改 ApolloClient
的构造函数,以定义每个 GraphQL 请求的默认的 headers
:
1 | const client: ApolloClient<NormalizedCacheObject> = new ApolloClient({ |
在解析不需要 token 的操作时(例如获取启动列表),服务可以忽略 token,因此对于客户端而言,可以在每个请求中都包含 token。
启用登录表单
已经完成了 login
变更的定义,但是还没有展示用户可以执行的表单。因为已经将用户 token 存储在本地,所以在下一节中,将使用 Apollo 客户端的本地状态 API 来增强表单的某些逻辑。
前端记事本,不定期更新,欢迎关注!