下一个具有Apollo useQuery的SSR依赖于另一个useQuery问题

时间:2020-04-20 19:48:30

标签: reactjs next.js apollo apollo-client

嗨,当我尝试将@apollo/client: latestnext:latestuseQuery挂钩和阿波罗缓存一起使用时,会遇到一些问题。 所以一步一步来: 我在_app.js文件中使用了with-apollo HOC(来自Next示例)。 创建Apollo客户端时,我会初始化状态并将其传递给ApolloCache

export default function createApolloClient(initialState, ctx) {
  const cache = new InMemoryCache();
  cache.writeData({
    data: {
      config: {
        first: 10,
        __typename: 'CONFIG',
      },
    },
  });
  // The `ctx` (NextPageContext) will only be present on the server.
  // use it to extract auth headers (ctx.req) or similar.
  return new ApolloClient({
    ssrMode: Boolean(ctx),
    link: new HttpLink({
      uri: 'https://api.graph.cool/simple/v1/cixmkt2ul01q00122mksg82pn', // Server URL (must be absolute)
      credentials: 'same-origin', // Additional fetch() options like `credentials` or `headers`
      fetch,
    }),
    cache,
    typeDefs,
    resolvers: {},
  });
}

在原始项目状态下基于请求标头生成的,这里我使用一些复制示例;

_app.js中,组件由ConfigProvider封装,它以这种方式从阿波罗缓存中查询数据:

export const CONFIG_QUERY = gql`
  query config {
    config @client {
      first
    }
  }
`;

export const ConfigProvider = ({ children }) => {
  const { data, loading } = useQuery(CONFIG_QUERY);

  console.log('loading', loading);
  const config = data ? data.config : {};
  return (
    <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>
  );
};

在ConfigProvider ConfigConusmer将config传递给PostsProvider之后,PostsProvider在另一个useQuery中使用该配置

export const PostsProvider = ({ children, config }) => {
  const { data } = useQuery(ALL_POSTS_QUERY, {
    variables: { ...allPostsQueryVars, first: config.first }
  });

  const allPosts = data ? data.allPosts : [];
  return (
    <PostsContext.Provider value={allPosts}>{children}</PostsContext.Provider>
  );
};

问题是,即使ConfigProvider中的缓存getDataFromTree()中已经有配置,但下次执行useQuery时,总是总是先返回loading: truedata: undefined,这使PostProvider的变量损坏了并且getDataFromTree引发错误。结果是所有PostProvider查询都在客户端而不是服务器端被调用。

有人可以为我解释这种行为吗?即使数据已经在阿波罗缓存中,为什么第一次遍历仍返回未定义状态?有办法使它起作用吗?

这是一个Codesanbox示例https://codesandbox.io/s/trusting-sinoussi-qw4qi

0 个答案:

没有答案