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

Gil*_*mes 10 javascript reactjs graphql apollo-client

我一直在关注本地状态的Apollo Client文档

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

export const GET_USER_ACCOUNTS = gql`
    query GetUserAccounts {
        userAccounts @client
        name @client
    }
`;
Run Code Online (Sandbox Code Playgroud)

userAccountsname在身份验证后都存储在我的缓存中:

export const GET_USER_ACCOUNTS = gql`
    query GetUserAccounts {
        userAccounts @client
        name @client
    }
`;
Run Code Online (Sandbox Code Playgroud)

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

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;

Run Code Online (Sandbox Code Playgroud)

由于文档指出,我未包含任何本地解析器:

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

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

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

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

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

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

任何建议表示赞赏

Dan*_*den 18

文档

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

换句话说,只需将一个空的resolvers对象添加到您的配置中,如下所示:

const client = new ApolloClient({
    cache,
    link,
    resolvers: {},
});
Run Code Online (Sandbox Code Playgroud)

  • [看起来](https://github.com/apollographql/react-apollo/blob/master/src/test-utils.tsx#L11-L19) `resolvers` 应该直接传递给 `MockedProvider`。这是有道理的——您可能想更换解析器进行测试。 (2认同)

小智 6

正如丹尼尔后来在上述答案评论中提到的那样,通过resolvers={{}}insideMockedProvider对我来说非常有用。它应该是这样的:

<MockedProvider mocks={mocks} addTypename={false} resolvers={{}}>
    <FooComponent />
</MockedProvider>
Run Code Online (Sandbox Code Playgroud)

它甚至解决了我在 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)
Run Code Online (Sandbox Code Playgroud)

干杯!