博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Apollo在React中实现GraphQL
阅读量:2508 次
发布时间:2019-05-11

本文共 10350 字,大约阅读时间需要 34 分钟。

This is a second part of a set articles exploring GraphQL technology. Refer to for the server setup which is necessary for this client side article.

这是探索GraphQL技术的系列文章的第二部分。 有关此客户端文章所必需的服务器设置,请参阅 。

In this section, we focus on how to implement GraphQL on a React client using Apollo. We begin by setting up a simple React Component. First we will have an app component which will be the parent component and another component to render the list of channels and a third component for creating new channels.

在本节中,我们重点介绍如何使用Apollo在React客户端上实现GraphQL。 我们首先建立一个简单的React Component。 首先,我们将有一个app组件,它将是父组件,另一个是呈现频道列表的组件,第三个是用于创建新频道的组件。

( )

We begin by defining a simple directory structure for our react application.

我们首先为我们的react应用程序定义一个简单的目录结构。

app/├── src/    └── app/              ├── components/              ├── ChannelList/                  └── ChannelList.jsx              └──  CreateChannel/                  └── CreateChannel.jsx        ├── app.jsx        ├── public/            └── index.html        ├── style/            └── style.scss        ├── .eslintrc.js        ├── webpack.config.js        └── package.json

( )

We create a simple functional component to show a list of channels from the server.

我们创建了一个简单的功能组件,以显示来自服务器的频道列表。

// src/app/components/ChannelList/ChannelList.jsximport React from 'react';const ChannelsList = () => {
... };

( )

To hook up our component with our query, we require the Apollo client and some other helper packages from react-apollo.

要将我们的组件与查询连接起来,我们需要Apollo客户端和react-apollo的其他一些帮助程序包。

npm i -S react-apollo #yarn add react-apollo

react-apollo allows you decorate your components with a higher order component called graphql to get your GraphQL data into the component. React Apollo also comes with ApolloClient, which is the core of Apollo that handles all the data fetching, caching and optimistic updates. To setup the Apollo Client, we will need to import the required components.

react-apollo允许您使用称为graphql高阶组件来装饰组件,以将GraphQL数据放入组件中。 React Apollo还附带了ApolloClient,它是Apollo的核心,负责处理所有数据提取,缓存和乐观更新。 要设置Apollo客户端,我们需要导入所需的组件。

// src/app/components/ChannelList/ChannelList.jsx...import {
gql, graphql} from 'react-apollo';...

Next, we decorate our component with a GraphQL higher-order component that takes the query and passes the data to the component:

接下来,我们用GraphQL高阶组件装饰组件,该组件接受查询并将数据传递给组件:

// src/app/components/ChannelList/ChannelList.jsx...const channelsListQuery = gql`   query ChannelsListQuery {     channels {       id       name     }   } `;const ChannelsListWithData = graphql(channelsListQuery)(ChannelsList);export default ChannelsListWithData;

The gql template tag is what you use to define GraphQL queries in your Apollo Client apps. It parses your GraphQL query which may then be consumed by Apollo Client methods. Whenever Apollo Client is asking for a GraphQL query you will always want to wrap it in a gql template tag.

gql模板标记是用于在Apollo Client应用程序中定义GraphQL查询的标记。 它解析您的GraphQL查询,然后Apollo Client方法可能会使用它。 每当Apollo Client请求GraphQL查询时,您总是希望将其包装在gql模板标签中。

When wrapped in the graphql HOC, our ChannelsList component will receive a prop called data, which will contain channels when it’s available, or error when there is an error. Data also contains a loading property, which is true when Apollo Client is still waiting for data to be fetched; this reduces the amount of code which we would otherwise write to monitor the state of the request. We can utilize the data in out component to notify the user accordingly about the state of the API request. We can then render the channels if they are fetched successfully.

当包装在graphql HOC中时,我们的ChannelsList组件将接收一个名为data的道具,该道具将在可用时包含通道,或者在出现错误时包含错误。 数据还包含加载属性,当Apollo Client仍在等待获取数据时,此属性为true; 这减少了我们将编写的用于监视请求状态的代码量。 我们可以利用数据输入输出组件来通知用户有关API请求状态的信息。 如果成功获取通道,我们便可以渲染它们。

// src/app/components/ChannelList/ChannelList.jsx...const ChannelsList = ({
data: {
loading, error, channels }}) => {
if (loading) {
return

Fetching Data...

; } if (error) {
return

{

error.message}

; } return
    {
    channels.map( channel =>
  • {
    channel.name}
  • ) }
; }; ...

( )

We then set up the main app component that will render the ChannelList component.

然后,我们设置将呈现ChannelList组件的主应用程序组件。

The app component is responsible for setting up the Apollo client and a network interface which defines the a http connection of our API.

该应用程序组件负责设置Apollo客户端和一个网络接口,该接口定义了我们API的http连接。

// src/app/app.jsximport {
ApolloClient, ApolloProvider, createNetworkInterface} from 'react-apollo’;import ChannelList from './components/ChannelList/ChannelList';const networkInterface = createNetworkInterface({
uri: 'http://localhost:7700/graphql',});const client = new ApolloClient({
networkInterface,});let app = document.querySelector('#app');render(

React , GraphQL , Apollo

, app)

The createNetworkInterface() function creates a simple HTTP network interface using the provided configuration object which includes the URI Apollo will use to fetch data from. The ApolloProvider HOC provides a client instance to a React component tree, similar to react-redux Provider component. It provides an ApolloClient instance to all of your GraphQL components that use the graphql function. If you do not add this component to the root of your React tree then your components enhanced with Apollo capabilities will not be able to function.

createNetworkInterface()函数使用提供的配置对象创建一个简单的HTTP网络接口,该配置对象包括Apollo将用于从中获取数据的URI。 ApolloProvider HOC向React组件树提供客户端实例,类似于react-redux Provider组件。 它为使用graphql函数的所有GraphQL组件提供ApolloClient实例。 如果您不将此组件添加到React树的根目录,那么使用Apollo功能增强的组件将无法运行。

A part from the client prop, ApolloProvider may also take an optional store which is an instance of Redux if we wish to include Redux in your project too. This ensures that we only use one HOC ApolloProvider and not react-redux Provider.

如果我们也希望将Redux包含在您的项目中,则ApolloProvider可能是Redux实例的一部分,它是client道具的一部分。 这确保了我们仅使用一个HOC ApolloProvider而不使用react-redux Provider

When we navigate to and issue our query, we see the following results.

当我们导航到并发出查询时,我们看到以下结果。

Subsequently when we open our application at , we can confirm the expected results.

随后,当我们在打开应用程序时,我们可以确认预期结果。

( )

Mutations are aimed at creating, updating or deleting of records. They basically perform the write operations equivalents in CRUD operations. In this section, we will create a mutation that creates a new channel. We will create a new component CreateChannel that will be responsible for creating the new channels. It’s a simple component that provides an input field and an event handler for the input.

突变旨在创建,更新或删除记录。 它们基本上执行与CRUD操作等效的写操作。 在本节中,我们将创建一个创建新频道的变体。 我们将创建一个新组件CreateChannel ,它将负责创建新通道。 它是一个简单的组件,为输入提供输入字段和事件处理程序。

// src/app/components/CreateChannel/CreateChannel.jsx...const CreateChannel = ({
mutate}) => {
const handleKeyUp = (evt) => {
if (evt.keyCode === 13) {
evt.persist(); mutate({
variables: {
name: evt.target.value } }) .then( res => {
evt.target.value = ''; }); } }; return ( );};const CreateChannelMutation = gql` mutation addChannel($name: String!) { addChannel(name: $name) { id name } }`;const CreateChannelWithMutation = graphql( CreateChannelMutation)(CreateChannel);export default CreateChannelWithMutation;

Using graphql with mutations makes it easy to bind actions to your components. Unlike queries, which provide a complicated object with lots of metadata and methods, mutations provide only a simple function to the wrapped component, in a prop called mutate. Most mutations will require arguments in the form of query variables.

使用带有突变的graphql可以轻松地将操作绑定到组件。 与为复杂对象提供大量元数据和方法的查询不同,在称为mutate的道具中,变异仅为包装的组件提供了简单的功能。 大多数变异将需要查询变量形式的参数。

...mutate({
variables: {
name: evt.target.value }})...

In the above snippet, we pass a name variable into mutate which will be passed to the actual query and will send to the server. The addChannel query below takes in the name variable passed in as part of the variables in mutate above.

在上面的代码片段中,我们将一个name变量传递给mutate ,该变量将传递给实际查询并发送给服务器。 下面的addChannel查询接受作为上面mutate变量的一部分传入的name变量。

...const CreateChannelMutation = gql`  mutation addChannel($name: String!) {    addChannel(name: $name) {      id      name    }  }`;...

We then wire it up in the main app component.

然后,我们将其连接到主应用程序组件中。

// src/app/app.jsx…import CreateChannel from './components/CreateChannel/CreateChannel’;… render(    
...
...
, app)

To make our input component call a GraphQL mutation, we have to wire it up with the GraphQL higher order component (HOC) from react-apollo. For mutations, the graphql HOC passes down a mutate prop, which we’ll call to execute the mutation. Inputting a new value and reloading the page shows the new channel.

为了使我们的输入组件称为GraphQL突变,我们必须将其与react-apollo中的GraphQL高阶组件(HOC)连接起来。 对于突变,graphql HOC传递了一个突变道具,我们将其称为执行突变。 输入新值并重新加载页面将显示新频道。

( )

GraphQL is a pretty alternative to the conventional REST implementations. Looking at the above application and making a comparison with Redux, we can see that the amount of code used is reduced by a very large percentage. We can avoid the whole concept of writing actions and reducers and configuring stores.

GraphQL是传统REST实现的不错替代方案。 查看上面的应用程序并与Redux进行比较,我们可以看到使用的代码量减少了很大的百分比。 我们可以避免编写动作和缩减器以及配置商店的整个概念。

In the next and final part of this series, we will focus on how to update the UI in realtime; how to perform operations and have the browser automatically update in three different ways; refetching queries, manually updating the client state based on the mutation result and using GraphQL subscriptions to notify the client about the updates. Unlike conventinal REST updates, GraphQL provides a more real-time view using subscriptions; updating data in one browser will automatically show changes in the next browser like push notifications.

在本系列的下一个也是最后一部分,我们将重点介绍如何实时更新UI。 如何执行操作并使浏览器以三种不同方式自动更新; 重新获取查询,基于变异结果手动更新客户端状态,并使用GraphQL订阅将更新通知给客户端。 与常规的REST更新不同,GraphQL使用订阅提供了更实时的视图。 在一个浏览器中更新数据将自动在下一个浏览器中显示更改,例如推送通知。

翻译自:

转载地址:http://qsuwd.baihongyu.com/

你可能感兴趣的文章
OKMX6Q在ltib生成的rootfs基础上制作带QT库的根文件系统
查看>>
zabbix
查看>>
多线程基础
查看>>
完美解决 error C2220: warning treated as error - no ‘object’ file generated
查看>>
使用SQL*PLUS,构建完美excel或html输出
查看>>
前后台验证字符串长度
查看>>
《算法导论 - 思考题》7-1 Hoare划分的正确性
查看>>
win64 Python下安装PIL出错解决2.7版本 (3.6版本可以使用)
查看>>
获取各种类型的节点
查看>>
表达式求值-201308081712.txt
查看>>
centos中安装tomcat6
查看>>
从Vue.js窥探前端行业
查看>>
学习进度
查看>>
poj3368 RMQ
查看>>
“此人不存在”
查看>>
github.com加速节点
查看>>
解密zend-PHP凤凰源码程序
查看>>
python3 序列分片记录
查看>>
Atitit.git的存储结构and 追踪
查看>>
atitit 读书与获取知识资料的attilax的总结.docx
查看>>