当变量发生变化时,Apollo 客户端缓存不会在查询时更新

问题描述

我对 Next、GraphQL 和 Apollo 完全陌生。我正在开发一个用于练习的 twitter-clone 东西。

索引页面显示包含所有新帖子的用户提要。我正在执行一个查询,该查询返回一个包含帖子和布尔值的对象“PaginatedPosts”,如果有更多帖子要获取(决定“加载更多帖子”按钮是否应该可见)。

如果您点击帖子的创建者(用户),您将进入一个页面例如:/user/8),其中包含该用户的个人资料及其所有帖子。我正在服务器端加载此页面,以获得更好的 SEO。我从 url 中获取用户 ID,然后进行查询获取用户,然后进行另一个查询获取他的帖子,其中包含一个带有他的 ID 的变量。

现在我的问题是,如果我转到用户的个人资料,查询会被 apollo 缓存,很酷。当我访问另一个用户的个人资料时,显示给我的帖子来自前一个用户(来自缓存)。我尝试添加 fetch-policy: no-cache 但如果我喜欢一个帖子,缓存不会自动更新。不过这似乎很奇怪,因为显示用户个人资料页面顶部的用户会正常更改。

这是我在前端用户页面上使用的代码

const {
    data: postsData,loading: postsLoading,fetchMore: fetchMorePosts,variables: postsVariables,} = useUserPostsQuery({
    notifyOnNetworkStatusChange: true,skip: !userData?.user,// skip if no user id
    variables: {
      limit: 15,userId: userData?.user?.id || -1,},});

创建 apollo 客户端函数

const createApolloClient = (ctx: any) => {
  let cookie = "";
  if (isServer() && ctx) {
    cookie = ctx.req.headers.cookie;
  }

  return new ApolloClient({
    uri: "http://localhost:4000/graphql",credentials: "include",headers: {
      cookie,cache: new InMemoryCache({
      typePolicies: {
        Query: {
          fields: {
            posts: {
              keyArgs: [],merge(
                existing: PaginatedPosts | undefined,incoming: PaginatedPosts
              ): PaginatedPosts {
                return {
                  ...incoming,posts: [...(existing?.posts || []),...incoming.posts],};
              },userPosts: {
              keyArgs: [],}),});
};

如果您需要更多信息,请告诉我。

解决方法

我最终将 userId 添加到 keyArgs(在创建 apollo 客户端函数中)。 像这样:

const createApolloClient = (ctx: any) => {
  let cookie = "";
  if (isServer() && ctx) {
    cookie = ctx.req.headers.cookie;
  }

  return new ApolloClient({
    uri: "http://localhost:4000/graphql",credentials: "include",headers: {
      cookie,},cache: new InMemoryCache({
      typePolicies: {
        Query: {
          fields: {
            posts: {
              keyArgs: [],merge(
                existing: PaginatedPosts | undefined,incoming: PaginatedPosts
              ): PaginatedPosts {
                return {
                  ...incoming,posts: [...(existing?.posts || []),...incoming.posts],};
              },userPosts: {
              keyArgs: ["userId"],// right there
              merge(
                existing: PaginatedPosts | undefined,}),});
};