📜  apollo graphql clearstore 示例 - Javascript (1)

📅  最后修改于: 2023-12-03 14:59:21.462000             🧑  作者: Mango

Apollo GraphQL ClearStore 示例 - JavaScript

简介

Apollo GraphQL是一个流行的工具套件,用于构建客户端和服务器端的GraphQL应用程序。ClearStore是它的一部分,它是一个本地状态管理解决方案,可以用来管理React组件状态。

本篇文章将介绍如何在JavaScript中使用Apollo GraphQL和ClearStore,以及如何构建一个示例应用程序。

准备工作

构建示例应用程序需要使用Node.js,因此请确保您已经安装了最新版本的Node.js。

此外,使用Apollo GraphQL需要在本地安装以下软件包:

npm install apollo-client graphql-tag graphql
步骤
1. 创建GraphQL服务器

首先,需要创建一个GraphQL服务器。可以使用任何GraphQL服务器实现,下面使用一个基于ExpressJS构建的示例服务器。

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');

const schema = buildSchema(`
  type Query {
    testValue: String
  }
`);

const root = {
  testValue: () => 'Hello world!',
};

const app = express();
app.use(
  '/graphql',
  graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
  })
);

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server started at http://localhost:${PORT}`);
});

此代码块创建了一个GraphQL服务器,该服务器具有一个查询类型(Query),可返回数据的字符串值。当请求到达/graphql时,服务器将把查询解析为testValue,该查询返回字符串'Hello world!'。

2. 创建Apollo GraphQL客户端

现在,需要在JavaScript应用程序中使用Apollo GraphQL的客户端,以从GraphQL服务器检索数据。

为此,请向应用程序添加以下代码,该代码创建了一个运行查询并返回响应的Apollo客户端实例。

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';

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

const GET_TEST_VALUE = gql`
  query {
    testValue
  }
`;

client.query({
  query: GET_TEST_VALUE,
}).then(result => console.log(result.data.testValue));

此代码块创建了一个Apollo客户端实例,该实例将查询发送到http://localhost:3000/graphql,并打印返回值。在本例中,服务器将返回字符串'Hello world!'。

3. 使用ClearStore管理状态

有了Apollo GraphQL客户端,现在可以向清除存储添加本地状态管理器。为了使事情简单,本例中的状态管理器只跟踪一个计数器。

为此,请在应用程序中添加以下代码:

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import { makeVar } from '@apollo/client';

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

const counterVar = makeVar(0);

const incrementCounter = () => {
  const current = counterVar();
  counterVar(current + 1);
};

const GET_TEST_VALUE = gql`
  query {
    testValue
    counter @client
  }
`;

client.cache.writeQuery({
  query: GET_TEST_VALUE,
  data: {
    counter: counterVar(),
  },
});

client.watchQuery({
  query: GET_TEST_VALUE,
}).subscribe(result => {
  console.log(result.data);
});

incrementCounter();
incrementCounter();

此代码块在makeVar函数中创建了一个计数器变量,该变量跟踪本地状态,使用writeQuery将计数器添加到缓存中,并使用watchQuery订阅查询,以便在数据更改时运行回调函数。最后,该代码块使用incrementCounter函数增加计数器的值两次,并打印出计数器的当前值。

4. 单元测试

构建完整的应用程序后,需要确保每个功能都按预期工作。为此,请执行以下命令运行单元测试:

npm install jest @apollo/client @apollo/react-hooks @testing-library/react --save-dev

具体测试代码实现如下:

import React from 'react';
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { renderHook, act } from '@testing-library/react-hooks';
import { useQuery, ApolloProvider } from '@apollo/react-hooks';

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

const GET_TEST_VALUE = gql`
  query {
    testValue
    counter @client
  }
`;

const TestComponent = () => {
  const { loading, error, data } = useQuery(GET_TEST_VALUE);
  const { counter } = data || {};
  return (
    <div>
      {loading ? 'Loading...' : error ? `Error! ${error.message}` : (
        <div>Test value: {data.testValue}, Counter: {counter}</div>
      )}
    </div>
  );
};

describe('TestComponent', () => {
  beforeEach(() => {
    client.cache.writeQuery({
      query: GET_TEST_VALUE,
      data: {
        testValue: 'Hello world!',
        counter: 0,
      },
    });
  });

  it('should render test value and counter', async () => {
    const { result } = renderHook(() => TestComponent(), {
      wrapper: ({ children }) => (
        <ApolloProvider client={client}>
          {children}
        </ApolloProvider>
      ),
    });

    await act(async () => {
      await new Promise(resolve => setTimeout(resolve, 0));
    });

    expect(result.current).toMatchSnapshot();

    act(() => {
      client.cache.writeQuery({
        query: GET_TEST_VALUE,
        data: {
          testValue: 'Cats!',
          counter: 2,
        },
      });
    });

    await act(async () => {
      await new Promise(resolve => setTimeout(resolve, 0));
    });

    expect(result.current).toMatchSnapshot();
  });
});

此代码块定义了一个测试套件,使用renderHook函数检查useQuery钩子是否按预期工作。

将测试插入__tests__文件夹并使用以下命令运行它:

jest
结论

在此示例应用程序中,使用了Apollo GraphQL客户端和ClearStore本地状态管理器。此外,还演示了如何编写单元测试,并查看其是否按预期工作。

如果您要构建GraphQL应用程序,ClearStore和Apollo GraphQL提供了一种效率和可扩展性的实现的方法。