面向新手的 GraphQL + React
作者:Ebenezer Don✏️
GraphQL 正在成为数据驱动应用程序的新标准。它是一种用于 API 的开源数据查询和操作语言,也是一种革命性的客户端与服务器之间通信的思维方式。
GraphQL 为您的 API 中的数据提供了完整且易于理解的描述,使客户端能够准确地询问他们所需要的内容,而不需要更多其他内容,使 API 随着时间的推移更容易发展,并支持强大的开发人员工具。
自 2015 年被 Facebook 公开发布以来,它就成为了 REST API 架构的强大替代品。
要开始在 React 应用程序中使用 GraphQL,您需要了解以下术语:
- 查询
- 突变
- 客户
GraphQL 查询
GraphQL查询类似于API 架构GET
中的请求REST
。查询用于从 GraphQL 服务器获取或检索数据。它们决定了我们接收数据的结构;这意味着,作为用户,您可以精确地请求您想要的内容以及您希望的数据结构。GraphQL 查询通常用括号括起来:
{
query_fields
}
查询字段是引用我们服务器上特定数据的键。这些数据的类型包括字符串、整数、浮点数、布尔值、ID 或对象。以下是 GraphQL 查询及其相应结果的示例:
// query
{
article(slug: "5-amazing-math-tricks-flyingturtle") {
title
description
author {
name
country
}
}
}
// result
{
"data": {
"article": {
"title": "5 Amazing Math Tricks",
"description": "here's what no one told you",
"author": {
"name": "Flying Turtle",
"country": "Nigeria"
}
}
}
}
在我们的示例中,请注意结果的结构与查询的结构相同。如果我们在查询中将 放在 之前description
,title
我们将以相同的顺序获得结果。article
第一个代码块第三行后面的括号包含查询参数。对于此查询,我们提供了文章 slug 作为我们需要从 GraphQL 服务器获取的特定文章的唯一标识符。
还需要注意的是,在第一个代码块的第 6 行,该author
字段有一个Object
类型。在这种情况下,我们还需要指定对象中需要的字段——在本例中name
是 和country
。
GraphQL 突变
将 GraphQL 突变与 REST API 架构进行比较时,它们类似于PUT
、、和方法PATCH
。突变,顾名思义,是修改 GraphQL 服务器上数据的请求。它可用于更新、插入或删除数据。POST
DELETE
GraphQL 中突变的语法与查询的语法类似fetch
,只是这次,我们将mutation
在第一个左花括号前添加关键字,然后传入我们想要突变的字段及其值作为参数:
// mutation
mutation {
updateArticle(slug: "5-amazing-math-tricks-flyingturtle", title: "just right") {
title
description
author {
name
country
}
}
}
// result
{
"data": {
"article": {
"title": "just right",
"description": "here's what no one told you",
"author": {
"name": "Flying Turtle",
"country": "Nigeria"
}
}
}
}
如果你注意到,我们还在突变请求中指定了返回值。这告诉 GraphQL 服务器在执行请求后应该返回什么。
GraphQL 客户端
curl
GraphQL 客户端使我们能够向 GraphQL 服务器发送 API 请求。以下是命令行中GraphQL 客户端的示例:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"query": "graphql_query"}' \
url_to_graphql_server
我们还可以使用 JavaScript fetch
API 向我们的 GraphQL 服务器发出 API 调用:
fetch('url_to_graphql_server', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({query: "graphql_query"})
})
.then(res => res.json())
.then(data => console.log({ data }));
这些方法看起来很简单,但当我们开始处理更复杂的查询、状态管理和缓存时,它们可能会变得复杂,并且可能需要大量可避免的代码。
幸运的是,有更强大的 GraphQL 客户端,如Apollo和Relay,它们专门用于处理 React 应用程序中的复杂查询、缓存和有效的状态管理。
以下是Apollo Client 文档对 Apollo 的描述:
Apollo Client是一个完整的 JavaScript 应用状态管理库。只需编写一个 GraphQL 查询,Apollo Client 就会负责请求和缓存数据,以及更新 UI。
理解 GraphQL 的最佳方式是使用它。让我们通过构建一个使用 Apollo 客户端调用 GraphQL 文章 API 的演示应用,学习如何在 React 中使用 GraphQL。
使用 GraphQL 构建 React 应用
我们首先使用 create-react-app 来启动一个新的 React 应用。如果你还没有安装 create-react-app,请在终端上运行:
npm i -g create-react-app
下一个:
create-react-app react_graphql
这将在名为 的新目录中引导一个 React 应用程序react_graphql
。要启动我们的应用程序,我们将从终端导航到新目录并运行npm start
:
cd react_graphql
npm start
如果您已正确完成所有操作,则浏览器中应该会打开如下页面:
设置 GraphQL
要在 React 中开始使用 GraphQL,我们需要安装以下软件包:
graphql
apollo-boost
,这将设置我们的 Apollo 客户端react-apollo
,其中包括为我们的 GraphQL 组件ApolloProvider
提供实例的组件ApolloClient
让我们在终端上运行以下命令:
npm i -s graphql apollo-boost react-apollo
这应该会在我们的应用程序中安装包并将它们添加到我们项目的依赖项中。
接下来,我们将设置应用程序以处理来自根索引文件的 GraphQL 查询。在我们的文件中,我们将分别从和包中/src/index.js
导入和 。让我们用以下代码块替换文件中当前的内容:ApolloClient
ApolloProvider
apollo-boost
react-apollo
/src/index.js
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import App from './App';
接下来,我们将设置 GraphQL 客户端。为此,我们将创建一个实例ApolloClient
并传入一个uri
属性。我们将在这里提供 GraphQL 端点:
// src/index.js
...
const client = new ApolloClient({
uri: 'https://awesome-node-graphql.herokuapp.com/graphql'
})
为了本文的目的,我使用 Node 和 Express.js 构建了一个 GraphQL 服务器( GitHub 仓库链接)。我们将能够通过向 GraphQL API 发送查询来获取文章应用程序的数据。
现在我们已经设置好了 GraphQL 客户端,接下来将它连接到 React 应用。我们将App
组件包装在之前导入的 中ApolloProvider
,然后为 Provider 提供一个client
prop:
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
我们的/src/index.js
文件现在看起来应该是这样的:
import React from 'react';
import ReactDOM from 'react-dom';
import ApolloClient from 'apollo-boost';
import { ApolloProvider } from 'react-apollo';
import App from './App';
const client = new ApolloClient({
uri: 'https://awesome-node-graphql.herokuapp.com/graphql'
})
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
使用查询组件获取数据
接下来,我们将使用Query
组件 fromreact-apollo
来访问我们的 GraphQL 端点。调用Query
组件时,我们将 GraphQL 查询作为其 prop 传入。首先,让我们/src/App.js
用以下代码块替换当前代码块中的内容:
// src/App.js
import React from 'react';
import { Query } from 'react-apollo';
import { gql } from 'apollo-boost';
这里,我们Query
从react-apollo
和gql
导入了组件apollo-boost
。gql
模板字面量标签将 GraphQL 查询字符串解析为标准 GraphQL 抽象语法树。我们声明一个变量 ,getAllArticles
并将我们的 GraphQL 查询赋值给它:
// src/App.js
...
const getAllArticles = gql`{
articles {
title
description
coverImageUrl
author {
name
country
}
}
}`
接下来,我们将创建App
组件,并在其中调用Query
from react-apollo
。该Query
组件使用 React 的render prop模式,并从 Apollo 客户端返回一个包含以下属性的对象:
loading
:根据请求状态返回布尔值error
:如果我们的请求不成功,则返回错误消息data
:从我们的服务器返回请求的数据
让我们将以下块添加到我们的src/App.js
文件中:
// src/App.js
...
const App = () => {
return (
<>
<Query query={getAllArticles}>
{({ loading, error, data }) => {
if (loading) return <p>Relax, it's worth the wait...</p>
if (error) return <p>Looks like we've got a problem...</p>
}}
</Query>
</>
);
}
使用获取的数据填充我们的页面
为了将获取的数据填充到页面中,我们将使用 JavaScriptmap
函数来迭代数据。最终/src/App.js
文件应如下所示:
import React from 'react';
import { Query } from 'react-apollo';
import { gql } from 'apollo-boost';
const getAllArticles = gql`{
articles {
title
description
coverImageUrl
author {
name
country
}
}
}`
const App = () => {
return (
<Query query={getAllArticles}>
{({ loading, error, data }) => {
if (loading) return <p>Relax, it's worth the wait...</p>
if (error) return <p>Looks like we've got a problem...</p>
return (
<div className="container">
<h1>Articles</h1>
<div className="row">
{data.articles.map(article => (
<div className="col-sm">
<div className="card" style={{width: "18rem"}}>
<img
src={article.coverImageUrl}
className="card-img-top"
style={{height: "10em"}}
alt="cover"
/>
<div className="card-body">
<h5 className="card-title">{article.title}</h5>
<p className="card-text">{article.description}</p>
<button className="btn btn-primary">Read</button>
</div>
</div>
</div>
))}
</div>
</div>
)
}}
</Query>
);
}
export default App;
最后,让我们将 Bootstrap CDN 添加到我们的/public/index.html
应用 CSS 样式文件中。我们将在标签定义<link>
之前粘贴以下标签<title>
:
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4"
crossorigin="anonymous">
当我们启动应用程序并在浏览器中导航时localhost:3000/
,我们应该看到类似这样的页面:
结论
在本文中,我们学习了 GraphQL 的基础知识以及如何在 React 应用程序中使用它。当然,GraphQL 不会立即取代 REST 架构,因为一夜之间重写所有现有平台非常困难,但最终它会实现的。
GraphQL 解决了数据驱动应用程序的诸多问题,包括信息的过度获取和不足。它使复杂的查询变得相对容易编写,并让客户端能够准确地获取他们想要的内容。
这是我们演示应用的GitHub 仓库链接。如果您需要有关 GraphQL 和 React 的进一步帮助,请随时通过Twitter联系我。
全面了解生产 React 应用程序
调试 React 应用可能很困难,尤其是当用户遇到难以复现的问题时。如果您对监控和跟踪 Redux 状态、自动显示 JavaScript 错误、跟踪缓慢的网络请求和组件加载时间感兴趣,请尝试 LogRocket。
LogRocket就像 Web 应用的 DVR,可以记录 React 应用上发生的所有事件。您无需猜测问题发生的原因,而是可以汇总并报告问题发生时应用程序的状态。LogRocket 还可以监控应用的性能,报告客户端 CPU 负载、客户端内存使用情况等指标。
LogRocket Redux 中间件包为您的用户会话增加了一层额外的可见性。LogRocket 会记录 Redux 存储中的所有操作和状态。
实现 React 应用程序调试方式的现代化 —开始免费监控。
新手入门的 GraphQL + React一文最先出现在LogRocket 博客上。
鏂囩珷鏉ユ簮锛�https://dev.to/bnevilleoneill/graphql-react-for-noobs-55ma