当变量发生变化时,Apollo Client 缓存不会根据查询更新
Apollo Client cache doesn't update on query when variables are changing
我对 Next、GraphQL 和 Apollo 完全陌生。我正在开发一个 Twitter 克隆的东西来练习。
索引页面显示包含所有新 post 的用户供稿。我正在执行一个查询 returns 一个对象“PaginatedPosts”,它包含 posts 和一个布尔值,如果有更多的 posts 要获取(决定是否“加载更多posts" 按钮是否可见。
如果您点击 post 的创建者(用户),您将进入一个包含用户个人资料的页面(例如:/user/8)以及他所有的 post。我正在服务器端加载此页面,以获得更好的 SEO。我从 url 获取用户 ID,然后我进行查询以获取用户,然后我进行另一个查询以获取他的 posts,其中包括一个带有他的 ID 的变量。
现在我的问题是,如果我转到用户的个人资料,查询会被 apollo 缓存,太棒了。当我访问另一个用户的个人资料时,显示给我的 posts 来自前一个用户(来自缓存)。我尝试添加 fetch-policy: no-cache
但如果我喜欢 post,缓存不会自动更新。这看起来很奇怪,因为显示在用户个人资料页面顶部的用户正常更改。
这是我在前端用户页面上使用的代码:
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: [],
merge(
existing: PaginatedPosts | undefined,
incoming: PaginatedPosts
): PaginatedPosts {
return {
...incoming,
posts: [...(existing?.posts || []), ...incoming.posts],
};
},
},
},
},
},
}),
});
};
如果您需要更多信息,请告诉我。
我最终将 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,
incoming: PaginatedPosts
): PaginatedPosts {
return {
...incoming,
posts: [...(existing?.posts || []), ...incoming.posts],
};
},
},
},
},
},
}),
});
};
我对 Next、GraphQL 和 Apollo 完全陌生。我正在开发一个 Twitter 克隆的东西来练习。
索引页面显示包含所有新 post 的用户供稿。我正在执行一个查询 returns 一个对象“PaginatedPosts”,它包含 posts 和一个布尔值,如果有更多的 posts 要获取(决定是否“加载更多posts" 按钮是否可见。
如果您点击 post 的创建者(用户),您将进入一个包含用户个人资料的页面(例如:/user/8)以及他所有的 post。我正在服务器端加载此页面,以获得更好的 SEO。我从 url 获取用户 ID,然后我进行查询以获取用户,然后我进行另一个查询以获取他的 posts,其中包括一个带有他的 ID 的变量。
现在我的问题是,如果我转到用户的个人资料,查询会被 apollo 缓存,太棒了。当我访问另一个用户的个人资料时,显示给我的 posts 来自前一个用户(来自缓存)。我尝试添加 fetch-policy: no-cache
但如果我喜欢 post,缓存不会自动更新。这看起来很奇怪,因为显示在用户个人资料页面顶部的用户正常更改。
这是我在前端用户页面上使用的代码:
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: [],
merge(
existing: PaginatedPosts | undefined,
incoming: PaginatedPosts
): PaginatedPosts {
return {
...incoming,
posts: [...(existing?.posts || []), ...incoming.posts],
};
},
},
},
},
},
}),
});
};
如果您需要更多信息,请告诉我。
我最终将 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,
incoming: PaginatedPosts
): PaginatedPosts {
return {
...incoming,
posts: [...(existing?.posts || []), ...incoming.posts],
};
},
},
},
},
},
}),
});
};