У меня есть игровое приложение 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 всегда возвращает ноль . Это указывает на то, что распознаватель вполне может найти объект кэша, который он всегда разрешает оставить пустым.