likes
comments
collection
share

如何在你的React应用程序中设置GraphQL

作者站长头像
站长
· 阅读数 11

在这篇文章中,我们将讨论如何在Apollo的帮助下在我们的React应用程序中实现GraphQL。有很多方法可以将GraphQL集成到我们的React应用程序中,但我确实更喜欢Apollo,而不是其他任何替代方案。

如果你还不熟悉GraphQL,你可以看看篇文章,它应该让你从根本上了解为什么它很重要,以及什么时候你可能想使用它。

如果你已经熟悉了,你可能还想看看这篇文章,在那里我们深入了解了如何用Node.js和Express.js建立GraphQL服务器。

包含本文中所有代码的仓库可以在这里找到。

请务必查看GraphQL服务器资源库,我们将在这里与之互动。

项目设置

1.设置React项目

首先,我们将从创建一个新的React项目开始。这可以通过npmyarn完成。我个人更喜欢yarn,但你也可以使用npm,这没有什么问题。

2.安装所需的依赖项

因为我们只做一些比较基本的工作,所以你只需要安装两个库来安装Apollo:

  • @apollo/client,它包含了几乎所有你可能需要的东西,以便设置Apollo客户端。
  • graphql,它提供了处理GraphQL查询的逻辑。

3.设置Apollo客户端

现在我们已经安装了这两个必要的依赖项,我们可以继续设置Apollo客户端。

首先,让我们从@apollo/client添加必要的导入:

import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
  • ApolloClient是一个主类,一旦实例化,将创建一个新的Apollo客户端实例(我们可以有多个)。
  • InMemoryCache是一个我们将使用的类,以便让Apollo客户端处理其请求的缓存过程。
  • ApolloProvider是一个组件,它接收客户端作为道具,这将允许我们将Apollo客户端注入到我们的应用程序。

现在让我们开始创建我们的第一个Apollo客户端:

const apolloClient = new ApolloClient({
  uri: 'http://localhost:8080/graphql',
  cache: new InMemoryCache(),
});

在这里你可以看到我们传递了两个属性给ApolloClient的结构体。这些属性用于指定后端GraphQL服务器的端点,以及Apollo将使用的缓存机制(我们传递了我们已经导入的默认机制 -InMemoryCache)。

这就是我们设置客户端所需的全部内容。

4.挂上Apollo客户端

设置过程的最后一步是将Apollo客户端连接到我们的React应用程序。我们可以通过在**组件中包装我们的**组件来做到这一点:

root.render(
  <React.StrictMode>
    <ApolloProvider client={apolloClient}>
      <App />
    </ApolloProvider>
  </React.StrictMode>
);

我们的App.js现在看起来应该是这样的:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
const apolloClient = new ApolloClient({
  uri: 'http://localhost:8080/graphql',
  cache: new InMemoryCache(),
});
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <ApolloProvider client={apolloClient}>
      <App />
    </ApolloProvider>
  </React.StrictMode>
);

使用 useQuery 获取数据

现在我们已经完成了Apollo客户端的设置,我们可以开始使用**@apollo/client库提供的一些工具,以及graphql**库。

对于这篇文章,应该还有一个资源库,它展示了一个使用Node.js和Express构建的基本GraphQL服务器,它允许我们访问一些作者和一些书籍。

一个作者可以有多本书,但一本书只能有一个作者,所以背后的模式看起来是这样的。

如何在你的React应用程序中设置GraphQL

作者GraphQL模式

如何在你的React应用程序中设置GraphQL

书籍GraphQL模式

让我们深入研究一些简单的用例,如检索作者和他们写的书。首先,我们必须创建一个GraphQL查询,这可以这样做。

const GET_AUTHORS_WITH_BOOKS_QUERY = gql`
    query {
      authors {
        id
        firstName
        lastName
        books {
          id
          title
        }
      }
    }
  `;

其次,我们必须使用useQuery钩子来查询我们的数据。

const { data, loading, error } = useQuery(GET_AUTHORS_WITH_BOOKS_QUERY);

正如你所看到的,我们将可以访问3个重要的属性。

  • 数据表示我们所查询的数据(根据我们之前定义的gql查询)。
  • 装载, 给我们提供请求的状态,特别是它是否已经完成加载
  • 错误, 在请求失败的情况下,它将向我们表明遇到了什么问题(验证、服务器停机等)。

而现在我们可以利用这些属性来处理我们的数据。

return (
    <div className="App">
      <div className="authors-container">
        {loading ? (
          <p>Loading Authors...</p>
        ) : error ? (
          <p>There was an issue loading the data...</p>
        ) : (
          data?.authors.map((author) => (
            <div className="user-record" key={author.id}>
              <p>Author: {author.firstName + " " + author.lastName}</p>
              <div className="author-books-container">
                {author?.books?.length && <h3>Books Written:</h3>}
                {author?.books?.map((book) => (
                  <div className="author-book-record">
                    <p>Book Title: {book.title}</p>
                  </div>
                ))}
              </div>
            </div>
          ))
        )}
      </div>
    </div>
  );

在这里,你可以看到,我们将检索我们所存储的所有作者,我们将在屏幕上显示他们的名字和他们所写的书的标题。

所有事先定义的属性都是反应式的,这意味着我们唯一要做的就是使用它们,一切都会很好地与我们的React应用程序挂钩;这意味着一旦加载过程完成,例如,加载变量的值将改变为falsy,然后我们就知道我们可以访问数据属性,或错误属性。

用useMutation更新/创建数据

更新或变异数据的过程与查询数据的过程相当类似,唯一的区别是我们使用的关键字(查询vs 突变),以及我们从调用钩子得到的东西,那就是一个数组,它为我们提供了一个触发变异的函数,以及我们从useQuery钩子得到的其他属性(数据, 装载, 错误).

在创建一个新的作者时,突变查询将看起来像这样。

const ADD_AUTHOR_MUTATION = gql`
    mutation CreateAuthor($firstName: String!, $lastName: String!) {
      createAuthor(
        firstName: $firstName
        lastName: $lastName
      ) {
        id
      }
    }
  `;

useMutation钩子的调用会是这样的。

const [addAuthor] = useMutation(ADD_AUTHOR_MUTATION);

我们将不使用 数据, 载入,和 错误属性,因为我们只需启动并忘记变异函数。

至于JSX和React代码的其余部分,我们将创建一个新的表单来输入作者的名字和姓氏,提交后我们将触发addAuthor函数调用来创建新的作者记录。

最后的App.js文件看起来会是这样的。

import { useState } from "react";
import { useQuery, useMutation, gql } from "@apollo/client";
import "./App.css";
function App() {
  const [authorFirstName, setAuthorFirstName] = useState("");
  const [authorLastName, setAuthorLastName] = useState("");
  const GET_AUTHORS_WITH_BOOKS_QUERY = gql`
    query {
      authors {
        id
        firstName
        lastName
        books {
          id
          title
        }
      }
    }
  `;
  const ADD_AUTHOR_MUTATION = gql`
    mutation CreateAuthor($firstName: String!, $lastName: String!) {
      createAuthor(
        firstName: $firstName
        lastName: $lastName
      ) {
        id
      }
    }
  `;
  const { data, loading, error, refetch } = useQuery(GET_AUTHORS_WITH_BOOKS_QUERY);
  const [addAuthor] = useMutation(ADD_AUTHOR_MUTATION);
  const handleSubmitForm = (e) => {
    e.preventDefault(); // Avoid refreshing the page
    addAuthor({
      variables: {
        firstName: authorFirstName,
        lastName: authorLastName,
      },
    });
    refetch();
  };
  return (
    <div className="App">
      <div className="authors-container">
        {loading ? (
          <p>Loading Authors...</p>
        ) : error ? (
          <p>There was an issue loading the data...</p>
        ) : (
          data?.authors.map((author) => (
            <div className="user-record" key={author.id}>
              <p>Author: {author.firstName + " " + author.lastName}</p>
              <div className="author-books-container">
                {author?.books?.length && <h3>Books Written:</h3>}
                {author?.books?.map((book) => (
                  <div className="author-book-record">
                    <p>Book Title: {book.title}</p>
                  </div>
                ))}
              </div>
            </div>
          ))
        )}
      </div>
      <div className="add-author-container">
        <form onSubmit={(e) => handleSubmitForm(e)}>
          <input
            type="text"
            value={authorFirstName}
            onChange={(e) => setAuthorFirstName(e.target.value)}
          />
          <input
            type="text"
            value={authorLastName}
            onChange={(e) => setAuthorLastName(e.target.value)}
          />
          <button type="submit">Add Author</button>
        </form>
      </div>
    </div>
  );
}
export default App;

所以,你有了它。你应该有一个基本的Apollo集成,现在你可以随着你的应用程序的复杂性的增加而建立。

随着你的应用程序的增长,你可能想开始考虑将查询和突变分离到独立的全局、功能或视图特定目录中。你可能还想考虑创建钩子来处理常见的查询或突变,这样你就可以提高代码的可重用性,以及消除多余的重复。

我希望你喜欢读这篇文章,它帮助你了解在Apollo的帮助下在你的React应用程序中设置GraphQL的基本原理。如果你觉得我错过了什么,请在下面的评论中告诉我。

直到下一次。干杯!

转载自:https://juejin.cn/post/7176274176607518779
评论
请登录