“在查询中找到了@client指令,但未指定客户端解析器”使用客户端缓存时警告

时间:2019-05-03 12:54:32

标签: javascript reactjs graphql apollo-client

我一直在本地国家关注Apollo Client docs

我已经实现了一个非常简单的客户端缓存查询:

export const GET_USER_ACCOUNTS = gql`
    query GetUserAccounts {
        userAccounts @client
        name @client
    }
`;
验证后,

userAccountsname都存储在我的缓存中:

    <Mutation
          mutation={API_TOKEN_AUTHENTICATION}
          variables={{ apiKey }}
          onCompleted={({
              apiTokenAuthentication: {
                  token,
                  userAccounts,
                  user: { givenName, familyName },
               },
          }) => {
             localStorage.setItem('token', token);
             client.writeData({
                 data: {
                     isLoggedIn: true,
                     userAccounts,
                     name: `${givenName} ${familyName}`,
                 },
             });
         }}
    >

并且我已经使用默认值预热了缓存:

import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';

const cache = new InMemoryCache();
const link = new HttpLink({
    uri: 'http://localhost:8002/v1/graphql',
    headers: {
        Authorization: `${localStorage.getItem('token')}`,
    },
});
const client = new ApolloClient({
    cache,
    link,
});
// set up the initial state
cache.writeData({
    data: {
        name: '',
        userAccounts: [],
        isLoggedIn: !!localStorage.getItem('token'),
    },
});

export default client;

自从文档说明以来,我没有包含任何本地解析器:

  

当Apollo Client执行此查询并尝试为isInCart字段查找结果时,它将执行以下步骤:

     

是否设置了与字段名称isInCart关联的解析器功能(通过ApolloClient构造函数resolvers参数或Apollo Client的setResolvers / addResolvers方法)?如果是,请运行并从resolver函数返回结果。

     

如果找不到匹配的解析器功能,请检查Apollo客户端缓存以查看是否可以直接找到isInCart值。如果是这样,请返回该值。

但是,尽管代码工作正常(它获取了我希望没有问题的值),但我仍然收到此警告:

  

在查询中找到@client指令,但未指定客户端解析器。现在,您可以将apollo-link-state解析器传递给ApolloClient构造函数。

我误会了吗?我是否应该以某种方式包括一个客户解析器?

任何建议表示赞赏

2 个答案:

答案 0 :(得分:4)

来自the docs

  

⚠️如果要使用Apollo Client的@client支持在不使用本地解析器的情况下查询缓存,则必须将空对象传递到ApolloClient构造函数resolvers选项中。如果没有此功能,Apollo Client将无法启用其集成的@client支持,这意味着基于@client的查询将被传递到Apollo Client链接链。您可以找到有关为什么需要这样做的更多详细信息here

换句话说,只需向您的配置添加一个空的解析器对象,如下所示:

const client = new ApolloClient({
    cache,
    link,
    resolvers: {},
});

答案 1 :(得分:3)

正如丹尼尔稍后在comments of the above answer中提到的那样,在resolvers={{}}内传递MockedProvider对我来说非常有用。它的外观如下:

<MockedProvider mocks={mocks} addTypename={false} resolvers={{}}>
    <FooComponent />
</MockedProvider>

它甚至解决了我在Circle CI中遇到的内存泄漏问题,因为似乎无处可解决。这是我收到的错误消息:

<--- Last few GCs --->

  154665 ms: Mark-sweep 949.1 (1434.4) -> 948.2 (1434.4) MB, 1979.3 / 0 ms [allocation failure] [GC in old space requested].
  156664 ms: Mark-sweep 948.2 (1434.4) -> 948.2 (1434.4) MB, 1999.7 / 0 ms [allocation failure] [GC in old space requested].
  158734 ms: Mark-sweep 948.2 (1434.4) -> 948.2 (1434.4) MB, 2069.7 / 0 ms [last resort gc].
  160810 ms: Mark-sweep 948.2 (1434.4) -> 948.1 (1434.4) MB, 2075.7 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x30ab306c9fa9 <JS Object>
    2: convertPropertyValueToJson(aka convertPropertyValueToJson) [/home/circleci/project/node_modules/typescript/lib/typescript.js:24737] [pc=0x2953c91d9878] (this=0x30ab30604189 <undefined>,valueExpression=0x39effa032fa9 <a NodeObject with map 0x35eb62463c11>,option=0x30ab30604189 <undefined>)
    3: /* anonymous */(aka /* anonymous */) [/home/circleci/project/node_modules/typescript/lib/type...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
Aborted (core dumped)

干杯!