React Apollo Client Resolver не получает данные из кэша - PullRequest
0 голосов
/ 28 января 2020

У меня есть игровое приложение React-App для отображения элементов списка дел, которые я переношу в Apollo Cache. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу создать «промежуточный слой graphql» на моем клиенте для обработки операций в клиентском кеше.

Проблема

У меня есть запрос подтверждения концепции называется getItemCount , который возвращает количество записей, хранящихся в массиве элементов внутри кэша.

Внутри клиентской функции распознавателя я использую объект cache для чтения запроса (cache.readQuery<any>(...)). Кажется, это всегда возвращает объект нулевой длины, а не точный массив, хранящийся в кэше.

Что я хочу сделать

Я хочу запрос кеш apollo внутри клиентских распознавателей для выполнения бизнес-логики c, связанной с локальным состоянием, и предоставления ее в виде пользовательских запросов graphql. Цель этого подхода - упростить адаптацию и повторное использование для других разработчиков тех же приложений.

Замечания

Я использую Apollo DevTools для проверки моего приложения и запроса поведение при выполнении.

Похоже, что запрос отправляется после того, как массив элементов полностью заполнен другими бизнес-логиками c и сохранен в кэше. Я могу видеть элементы, хранящиеся в кеше, используя расширение DevTools.

Кроме того, есть другие логи c, которые также извлекают элементы из кеша, и они работают так, как и ожидалось.

Исходный код

Я следовал частям Apollo Fullstack Tutorial , чтобы создать несколько пользовательских клиентских распознавателей .

import gql from "graphql-tag";
import { ApolloCache } from "apollo-cache";
import { Resolvers } from "apollo-client";

export const typeDefs = gql`
  type ToDoItem {
    userId: Int!
    id: Int!
    title: String!
    completed: Boolean!
  }

  extend type Query {
    test: String!
    getItemCount: Int!
  }
`;

type ResolverFunction = (
  parent: any,
  args: any,
  { cache }: { cache: ApolloCache<any> }
) => any;

//this can contain as many resolver functions as possible
interface ResolverMap {
  [field: string]: ResolverFunction;
}


interface ClientResolvers extends Resolvers {
  Query: ResolverMap;
}

export const resolvers: ClientResolvers = {
  Query: {
    test(parent: any, _: any, { cache }) {
      return "Hello, World!";
    },
    getItemCount(parent: any, _: any, { cache }) {
      const GET_ITEMS = gql`
        query GetItems {
          items
        }
      `;

      const data = cache.readQuery<any>({
        query: GET_ITEMS,
      });

      if (!data) {
        return -1;
      }

      return data.items.length;
    }
  }
};

И в файле App.tsx я изначально заполняю кеш примерно так.

import React from "react";
import { ApolloClient, HttpLink } from "apollo-boost";
import { ApolloProvider } from "@apollo/react-hooks";
import { InMemoryCache } from "apollo-cache-inmemory";
import { typeDefs, resolvers } from "./Clients/ClientResolvers";

const apolloClient = new ApolloClient({
  link: new HttpLink({
    uri: ""
  }),
  cache: new InMemoryCache({
    addTypename: false
  }),
  typeDefs,
  resolvers
});

apolloClient.writeData({
  data: {
    searchValue: "",
    items: [
      {
        id: -1,
        userId: 2,
        title: "test",
        completed: true
      }
    ]
  }
});

//...

У меня есть пользовательский хук, который читает и записывает данные элементов в и из кеша, получая клиент через useApolloClient() для записи и использования useQuery для чтения. Это работает, как и ожидалось.

Однако, когда я выполняю вызов graphql для моего пользовательского распознавателя запросов (который на самом деле работает, учтите пример запроса 'test'), запрос getItemCount всегда возвращает ноль . Это указывает на то, что распознаватель вполне может найти объект кэша, который он всегда разрешает оставить пустым.

...