# 简介 GraphQL 与 Apollo Client

URL: https://caijiao.org/react/chapter14/graphql
Source: docs/react/chapter14/graphql.md
Description: GraphQL 是一种用于 API 查询语言，能够允许客户端请求精确的数据。Apollo Client 是一个用于与 GraphQL 后端交互的强大库，提供了高效的数据管理和查询功能。本文将简要介绍 GraphQL 的基本概念以及 Apollo Client 的使用方法，帮助开发者快速上手。

GraphQL 是一种用于 API 查询语言，它不同于传统的 RESTful API，允许客户端精确指定需要的数据。它提供了更加灵活和高效的方式来请求和修改数据，避免了传统 REST API 中“过度获取”或“获取不足”的问题。Apollo Client 是一个流行的 JavaScript 库，帮助开发者在客户端应用中轻松实现与 GraphQL 后端的交互。

## GraphQL 基础

GraphQL 由三个核心部分组成：

1. **查询（Query）**：客户端通过查询请求需要的数据，查询可以指定字段层级，减少了不必要的数据传输。
2. **变更（Mutation）**：客户端通过变更操作来修改服务器端的数据。
3. **订阅（Subscription）**：允许客户端订阅特定的数据变动，实时获取数据更新。

GraphQL 的最大优势是客户端能够控制所需的数据精度，从而提高了数据获取的效率。

## Apollo Client 简介

Apollo Client 是一个用于在客户端实现 GraphQL 的 JavaScript 库。它使得与 GraphQL 后端的交互变得更加简洁、灵活，并且能够高效地处理数据缓存、查询、订阅等功能。

### Apollo Client 特性

- **简化查询和变更操作**：通过 `useQuery`、`useMutation` 等 React Hook，Apollo Client 提供了简化的 API 来进行 GraphQL 查询和变更。
- **数据缓存**：Apollo Client 会自动缓存服务器返回的数据，从而减少不必要的请求，提高应用的性能。
- **本地状态管理**：Apollo Client 除了支持与 GraphQL 后端的交互，还可以作为本地状态管理库使用，简化前端数据管理。
- **支持订阅**：通过 WebSocket，Apollo Client 支持 GraphQL 订阅，能够实现实时数据更新。

## 使用 Apollo Client 与 GraphQL

在 React 应用中集成 Apollo Client 一般分为以下几步：

1. **安装依赖**

```bash
npm install @apollo/client graphql
````

2. **配置 Apollo Client**

首先，创建一个 Apollo Client 实例，并在应用根组件中提供该实例。

```javascript
import React from 'react';
import ReactDOM from 'react-dom';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';

const client = new ApolloClient({
  uri: 'https://example.com/graphql', // GraphQL 后端的地址
  cache: new InMemoryCache(), // 缓存配置
});

function App() {
  return (
    
  );
}

ReactDOM.render(, document.getElementById('root'));
```

3. **查询数据**

使用 `useQuery` Hook 来发起查询请求，并渲染返回的数据。

```javascript
import React from 'react';
import { useQuery, gql } from '@apollo/client';

const GET_DATA = gql`
  query {
    getItems {
      id
      name
    }
  }
`;

function ItemList() {
  const { loading, error, data } = useQuery(GET_DATA);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.getItems.map(item => (
        <li key={item.id}>{item.name}</li>
      ))}
    </ul>
  );
}

export default ItemList;
```

4. **变更数据**

使用 `useMutation` Hook 来进行变更操作。

```javascript
import React, { useState } from 'react';
import { useMutation, gql } from '@apollo/client';

const ADD_ITEM = gql`
  mutation AddItem($name: String!) {
    addItem(name: $name) {
      id
      name
    }
  }
`;

function AddItemForm() {
  const [name, setName] = useState('');
  const [addItem, { data, loading, error }] = useMutation(ADD_ITEM);

  const handleSubmit = e => {
    e.preventDefault();
    addItem({ variables: { name } });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={name}
        onChange={e => setName(e.target.value)}
        placeholder="Item name"
      />
      <button type="submit" disabled={loading}>Add Item</button>
      {error && <p>Error: {error.message}</p>}
    </form>
  );
}

export default AddItemForm;
```

## 总结

GraphQL 提供了一个高效灵活的方式来处理数据请求，而 Apollo Client 通过其丰富的功能，使得在 React 中与 GraphQL 后端的交互变得更加简便。通过 Apollo Client，开发者可以轻松地进行查询、变更和订阅操作，同时还可以高效地管理缓存和本地状态，从而优化前端应用的性能和用户体验。
