Apollo链接状态仅在定义冗余查询时有效?

时间:2018-05-21 02:40:09

标签: apollo

我有Apollo链接状态工作:

header("Location: prueba.php?record_id=" . urlencode($row['id']));

然而,大多数在线示例都不需要定义查询解析器。如果我删除下面的代码,那么来自前端的查询将始终返回默认状态,该突变似乎没有效果:

import React from 'react';
import ReactDOM from 'react-dom';
import { HttpLink, InMemoryCache, ApolloClient } from 'apollo-client-preset';
import { WebSocketLink } from 'apollo-link-ws';
import { ApolloLink, split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import { AUTH_TOKEN } from './constant';
import RootContainer from './components/RootContainer';
import { ApolloProvider } from 'react-apollo';
import { withClientState } from 'apollo-link-state';
import { gql } from 'apollo-boost';

const httpLink = new HttpLink({ uri: 'http://localhost:4000' });

const middlewareLink = new ApolloLink((operation, forward) => {
  const tokenValue = localStorage.getItem(AUTH_TOKEN);
  operation.setContext({
    headers: {
      Authorization: tokenValue ? `Bearer ${tokenValue}` : '',
    },
  });
  return forward(operation);
});

const httpLinkAuth = middlewareLink.concat(httpLink);

const wsLink = new WebSocketLink({
  uri: `ws://localhost:4000`,
  options: {
    reconnect: true,
    connectionParams: {
      Authorization: `Bearer ${localStorage.getItem(AUTH_TOKEN)}`,
    },
  },
});

const link = split(
  ({ query }) => {
    const { kind, operation } = getMainDefinition(query);
    return kind === 'OperationDefinition' && operation === 'subscription';
  },
  wsLink,
  httpLinkAuth,
);

const cache = new InMemoryCache();

const stateLink = withClientState({
  cache,
  defaults: {
    groupMenuStatus: {
      __typename: 'GroupMenuStatus',
      isOpen: false,
    },
  },
  resolvers: {
    Mutation: {
      updateGroupMenuStatus: (_, { isOpen }, { cache }) => {
        const data = {
          groupMenuStatus: {
            __typename: 'GroupMenuStatus',
            isOpen,
          },
        };
        cache.writeData({ data });
        return null;
      },
    },
    Query: {
      groupMenuStatus: async (_, args, { cache }) => {
        const query = gql`
          query groupMenuStatus {
            groupMenuStatus @client {
              isOpen
            }
          }
        `;
        const res = cache.readQuery({ query });
        return res.groupMenuStatus;
      },
    },
  },
});

const client = new ApolloClient({
  link: ApolloLink.from([stateLink, link]),
  cache,
  connectToDevTools: true,
});

const token = localStorage.getItem(AUTH_TOKEN);

ReactDOM.render(
  <ApolloProvider client={client}>
    <RootContainer token={token} />
  </ApolloProvider>,
  document.getElementById('root'),
);

1 个答案:

答案 0 :(得分:1)

根据https://www.apollographql.com/docs/link/links/state.html上的官方文档

Query resolvers are only called on a cache miss. Since the first time you call the query will be a cache miss, you should return any default state from your resolver function.

因此,如果您定义默认值,则永远不会调用查询解析器。 (您的定义正确,实际上叫做Query

如果不声明默认值,则可以使用查询解析器在缓存上写一些东西(然后将不再调用查询解析器),或者可以仅返回一些值,并且将在每个位置调用解析器。时间。

我使用它,例如在第一次调用时获取用户地理位置信息,现在这是我的默认值,并且不再调用解析器。

检查我的用例:

Query: {
    async smePosition(_: any, {}: any, { cache }: IContext): Bluebird<any> {
      return new Bluebird((resolve: any, reject: any): void => {
        window.navigator.geolocation.getCurrentPosition(
          ({coords: {latitude: lat, longitude: lng}}) => {
            const data = {
              smePosition: {
                __typename: 'SMe',
                position: {lat, lng , __typename: 'IPosition'},
              },
            }
            cache.writeData({ data })
            resolve()
          },
        )
      })
    },
  },

在这种情况下,我没有为'smePosition'定义默认值