发布于 2026-01-06 1 阅读
0

使用 React 调用 Apollo GraphQL 服务器

使用 React 调用 Apollo GraphQL 服务器

欢迎在推特上关注我,我很乐意接受您对话题或改进方面的建议。/克里斯

本文是 GraphQL 系列文章的一部分。

本文将介绍如何从前端与 Apollo GraphQL 服务器进行交互。如果您还不熟悉如何创建 Apollo 服务器,请先阅读这篇文章:创建 Apollo 服务器

本文将探讨以下内容:

  • 设置时,我们需要指定服务器的 URL 并实例化一个客户端。
  • 查询,我们可以使用查询组件来查询数据。
  • 变异,我们可以使用变异组件来执行变异操作。
  • 轮询/显式 获取,Apollo 在轮询、显式获取和数据获取方面提供了一些不错的功能。

设置

要使用 GraphQL 设置 React 应用,我们需要一些库。`GraphQL`apollo-boost提供我们需要实例化的对象并提供了一个高阶Provider ,我们需要用它来包装我们的应用。首先,请进行必要的安装:react-apolloapollo-boostApolloClientURLreact-apolloApolloProvider

yarn add react-apollo apollo-boost graphql
Enter fullscreen mode Exit fullscreen mode

安装完成后,我们就可以进行设置了。请前往index.js并输入以下内容:

import React, { Component } from "react";
import ApolloClient from "apollo-boost";
import { ApolloProvider } from "react-apollo";
import Local from ./components/Local;

const localGraphQL = "http://localhost:4000/graphql";

const client = new ApolloClient({
  uri: localGraphQL
});
class App extends Component {
  render() {
    return (
      <ApolloProvider client={client}>
        <div>
          <h2>My first Apollo app </h2>
        </div>
     </ApolloProvider>
    );
  }
}
export default App;
Enter fullscreen mode Exit fullscreen mode

上面我们首先实例化ApolloClient它,并在过程中为其提供urlGraphQL 服务器的位置。

其次,我们将整个应用程序封装在我们的实例中ApolloProvider,并且我们还client使用我们的实例设置了它的属性ApolloClient

现在我们已准备好与 GraphQL 服务器进行交互。

询问

要查询 Apollo 服务器,我们需要做三件事:

  • 请填写我们的gql查询
  • 利用react-apollo库提供的查询组件
  • 渲染响应

要编写gql查询,我们需要先导入相关库graphql-tag,然后编写 GraphQL 查询,如下所示:

const getRates = gql`
{
  rates(currency: “USD”) {
    currency
    rate
  }
}`;
Enter fullscreen mode Exit fullscreen mode

接下来,我们需要Query从 [此处应填写来源名称] 导入该组件react-apollo,并将其作为输入属性提供我们刚刚定义的查询语句,如下所示:

const Data = () => (
  <Query query={getRates} >
  // render the query results
  </Query>
);
Enter fullscreen mode Exit fullscreen mode

在组件的第一个子组件中,Query我们调用了一个以对象作为参数的函数。该对象具有以下属性:

  • 正在加载,只要我们的查询还没有完成,这就是true
  • 如果查询返回错误,则表示出现错误。
  • 数据,即我们查询得到的数据结果。

现在我们已经了解了这些属性以及如何使用它们,让我们把所有内容整合起来:

import React from "react";
import { Query } from "react-apollo";
import gql from "graphql-tag";
const getRates = gql`
{
  products(type: "DVD") {
    name
    price
  }
}`;
const Data = () => (
  <Query query={getRates} >
  {({ loading, error, data }) => {
  if (loading) return <p>Loading…</p>;
  if (error) return <p>Error :(</p>;
  return data.products.map(({ name, price }) => (
    <div key={name}>
      <p>{`${name}: ${price}`}</p>
    </div>
   ));
  }}
</Query>
);
export default Data;
Enter fullscreen mode Exit fullscreen mode

我们现在已经学会了如何从 GraphQL 服务器读取数据并将其呈现给用户。

轮询

你不仅需要获取数据,有时还需要定期获取数据,而无需显式导航到特定页面或按下特定按钮来触发 GET 请求。例如,我们在聊天应用程序中使用此功能来实现实时性。我们这里所说的轮询,就是按照我们指定的固定时间间隔获取数据。Query我们学习使用的组件内置了轮询功能,我们只需要设置一个pollInterval属性来指定两次数据获取之间的时间间隔(以毫秒为单位)。让我们来看看具体示例:

import React from "react";
import { Query } from "react-apollo";
import gql from "graphql-tag";
const GET_DATA = gql`
{
  products {
    name
    id
  }
}
`;
const DataPull = () => (
  <Query query={GET_DATA} pollInterval={500}>
  {(loading, error, data, startPolling, stopPolling) => {
  if (loading) return null;
  if (error) return `Error!: ${error}`;
    return (
     <React.Fragment>
      {data.products.map(p => <div>{p.name}</div>)}
      <button onClick={()=> startPolling()}>Start polling</button>
      <button onClick={() => stopPolling()}>Stop polling</button>
    </React.Fragment>;
    )
}}
</Query>
);
export default DataPull;
Enter fullscreen mode Exit fullscreen mode

以上我们介绍了以下新概念:

  • pollInterval参数用于指定轮询间隔,单位为毫秒。如您所见,我们将其设置为500例如半秒。
  • startPolling函数允许我们在之前停止轮询后重新启动轮询。
  • stopPolling函数允许我们随时停止轮询。

重新获取

有时我们会遇到需要显式获取数据以确保查看最新数据的情况。这样做的目的是为了响应用户操作,而不是轮询。让我们来看看如何使用此refetch功能:

import React from "react";
import { Query } from "react-apollo";
import gql from "graphql-tag";
const GET_DATA = gql`
{
  products {
    name
    id
  }
}
`;
const Refetch = () => (
  <Query query={GET_DATA}>
  {(loading, error, data, refetch) => {
  if (loading) return null;
  if (error) return `Error!: ${error}`;
  return (
    <React.Fragment>
      <div>
        {data.prop}
        <button onClick={() => refetch()}>Fetch</button>
      </div>
   </React.Fragment>
  )
}}
</Query>
);
export default Refetch;
Enter fullscreen mode Exit fullscreen mode

refetch上面我们可以看到,我们给Query子函数添加了另一个参数,如下所示:

{(loading, error, data, refetch) => {
}}

Enter fullscreen mode Exit fullscreen mode

这个refetch参数是一个我们可以调用的函数,因此我们可以像这样把它连接到标记中的一个按钮:

<button onClick={() => refetch()}>Fetch</button>
Enter fullscreen mode Exit fullscreen mode

突变

当我们对 GraphQL 服务器执行 mutation 操作时,需要执行以下操作:

  • 调用正确的突变

  • 使用来自 Mutation 组件react-apollo

以上内容听起来似乎没什么特别的,实际上也确实如此。那么,让我们从第一件事开始,也就是我们的变更查询:

我们将使用库gql中的辅助函数graphql-tag来创建 mutation 查询。之后,我们使用关键字 `mutation` mutation,然后给 mutation 命名并指定其输入参数$person。此时,我们的查询如下:

const ADD_PERSON = gql`
mutation AddPerson($person: Person!) {
}
`;
Enter fullscreen mode Exit fullscreen mode

现在我们可以调用addPerson在 GraphQL 服务器中定义的实际 mutation 了。你的 mutation 查询现在应该如下所示:

const ADD_PERSON = gql`
  mutation AddPerson($person: Person!) {
    addPerson(person: $person) {
      id
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

接下来,我们将通过与 React 组件配合使用来应用 mutation 查询Mutation。该组件需要两样东西:

  • 填充属性信息mutation
  • 定义组件的子组件时Mutation,我们需要为其提供一个函数,该函数的第一个参数包含mutation触发变更发生的函数,第二个参数则是一个包含以下属性的对象dataerrorloading

让我们从组件的初始使用部分开始Mutation,并设置其mutation属性,如下所示:

import React from "react";
import { Mutation } from "react-apollo";
import gql from "graphql-tag";
const ADD_PERSON = gql`
  mutation AddPerson($person: Person!) {
    addPerson(person: $person) {
      id
    }
  }
`;
<Mutation mutation={ADD_PERSON}>
</Mutation>
Enter fullscreen mode Exit fullscreen mode

上面我们已经使用了Mutation组件,并mutation通过变更查询设置了属性ADD_PERSON。接下来是定义Mutation组件的子组件。正如我们之前提到的,子组件是一个函数,如下所示:

(addPerson, { data, loading, error }) => (
// JSX
)
Enter fullscreen mode Exit fullscreen mode

上述函数预期返回 JSX 代码。我们需要定义一段 JSX 代码,以便使用以下功能:

  • addPerson(),此函数将执行变更查询。
  • 加载中,这个布尔值将告诉我们变更是否正在进行中,使用此值来决定是否使用加载指示器。
  • 数据,这是你的变更查询完成后返回的数据。

现在我们了解了函数参数的用途,接下来让我们定义 JSX 代码。通常,我们需要定义一个表单来收集数据,所以我们来这样做:

<form onSubmit={e => {
  e.preventDefault();
  addPerson({ variables: { person: { name: input.value } } });
  input.value = “”;
}} >
  <input ref={node => { input = node; }} />
  <button type=”submit”>Add Person</button>
  {loading &&
  <div>adding person…</div>
  }
  { data &&
  <div>response data</div>
  }
  { error &&
  <div>Error adding person…</div>
  }
</form>
Enter fullscreen mode Exit fullscreen mode

如上图所示,我们有一个表单、一个输入字段和一个可点击的按钮。我们将该addPerson()方法连接到onSubmit()表单。请注意,我们也解决了如何将数据传递给变更查询的问题。我们给该addPerson()方法提供一个对象,该对象有一个属性,variables我们将该属性赋值给一个对象person。该person属性与变更查询中的输入参数相同。

其他字段用作条件 JSX data,如果它们的值为真,loadingerror选择显示它们。

就是这样,调用带有某些参数的 mutation 并显示响应(无论是实际数据还是错误)就是这么简单。

以下是全部代码。

import React from "react";
import { Mutation } from "react-apollo";
import gql from "graphql-tag";
const ADD_PERSON = gql`
  mutation AddPerson($person: Person!) {
    addPerson(person: $person) {
      id
    }
  }
`;
const DataInput = () => {
  let input;
  return (
    <Mutation mutation={ADD_PERSON}>
    {(addPerson, { data, loading, error }) => (
    <div>
      <form onSubmit={e => {
        e.preventDefault();
        addPerson({ variables: { person: { name: input.value } } });
        input.value = “”;
    }} >
      <input ref={node => { input = node; }} />
      <button type=submit>Add Person</button>
      {loading &&
      <div>adding person…</div>
      }
      { data &&
      <div>response data</div>
      }
      { error &&
      <div>Error adding person…</div>
      }
    </form>
  </div>
)}
</Mutation>)
}
export default DataInput;
Enter fullscreen mode Exit fullscreen mode

概括

我们研究了从后端与数据交互的不同方法。

  • 获取数据时,如果我们使用该Query组件,可以通过向其query属性填充gql问题来获取数据。

  • 轮询数据pollInterval:如果我们在组件上设置了该属性,Query就可以轮询我们的 GraphQL 后端。

  • 通过使用额外的参数,我们可以显式地获取refetch数据,以便在需要时进行显式获取。

  • 通过触发突变,我们了解到我们可以利用该Mutation组件来执行突变。

文章来源:https://dev.to/azure/consuming-an-apollo-graphql-server-usingreact-3kk4