问题描述
我有一个由2个组件组成的页面,每个组件都有自己的数据请求 例如
<MovieInfo movieId={queryParamsId}/> const GET_MOVIE_INFO = `gql query($id: String!){ movie(id: $id){ name description } }`
下一个组件
<MovieActors movieId={queryParamsId}/> const GET_MOVIE_ACTORS = `gql query($id: String!){ movie(id: $id){ actors } }`
对于每个查询,我都使用Apollo Hook
const {数据,加载,错误} = usequery(get_data,{variable:{id:queryparamsid}}))
一切都很好,但是我收到了警告消息:
替换查询对象的电影字段时可能会丢失缓存数据. 要解决此问题(这不是Apollo客户端中的错误),请确保类型电影的所有对象都有ID,或为查询字段定义自定义合并函数,因此InmemoryCache可以安全地合并这些对象:{... }
与Google Chrome可以使用,但是此错误会影响Safari浏览器.一切都在粉碎.我100%确定这是因为此警告消息.在第一个请求中,我在缓存中将电影数据设置为同一查询,我刚刚用新数据替换旧数据,因此以前的缓存数据未定义.我该如何解决这个问题?
推荐答案
已解决!
cache: new InMemoryCache({ typePolicies: { Query: { fields: { YOUR_FIELD: { merge(existing = [], incoming: any) { return { ...existing, ...incoming }; // this part of code is depends what you actually need to do, in my case i had to save my incoming data as single object in cache } } } } } }) });
其他推荐答案
这是托马斯提到的相同解决方案,但有点短
const cache = new InMemoryCache({ typePolicies: { Query: { fields: { YOUR_FIELD: { // shorthand merge: true, }, }, }, }, });
这与以下
相同const cache = new InMemoryCache({ typePolicies: { Query: { fields: { YOUR_FIELD: { merge(existing, incoming, { mergeObjects }) { return mergeObjects(existing, incoming); }, }, }, }, }, });
其他推荐答案
其他答案仍然可以工作,但是从Apollo客户端> = 3.3 更轻松的选项这不需要指定特定字段或定制合并函数.相反,您只需要指定类型,它将合并该类型的所有字段:
const cache = new InMemoryCache({ typePolicies: { YOUR_TYPE_NAME: { merge: true, } } });
从您的示例查询中,我想一个id字段应该可用吗?尝试在查询中请求ID,这应该以更理想的方式解决问题.
问题描述
I have a page that consists of 2 components and each of them has its own request for data for example
<MovieInfo movieId={queryParamsId}/> const GET_MOVIE_INFO = `gql query($id: String!){ movie(id: $id){ name description } }`
Next component
<MovieActors movieId={queryParamsId}/> const GET_MOVIE_ACTORS = `gql query($id: String!){ movie(id: $id){ actors } }`
For each of these queries I use apollo hook
const { data, loading, error } = useQuery(GET_DATA, {variable: {id: queryParamsId}}))
Everything is fine, but I got a warning message:
Cache data may be lost when replacing the movie field of a Query object. To address this problem (which is not a bug in Apollo Client), either ensure all objects of type Movie have IDs, or define a custom merge function for the Query.movie field, so InMemoryCache can safely merge these objects: { ... }
It's works ok with google chrome, but this error affects Safari browser. Everything is crushing. I'm 100% sure it's because of this warning message. On the first request, I set Movie data in the cache, on the second request to the same query I just replace old data with new, so previous cached data is undefined. How can I resolve this problem?
推荐答案
Solved!
cache: new InMemoryCache({ typePolicies: { Query: { fields: { YOUR_FIELD: { merge(existing = [], incoming: any) { return { ...existing, ...incoming }; // this part of code is depends what you actually need to do, in my case i had to save my incoming data as single object in cache } } } } } }) });
其他推荐答案
Here is the same solution mentioned by Thomas but a bit shorter
const cache = new InMemoryCache({ typePolicies: { Query: { fields: { YOUR_FIELD: { // shorthand merge: true, }, }, }, }, });
This is same as the following
const cache = new InMemoryCache({ typePolicies: { Query: { fields: { YOUR_FIELD: { merge(existing, incoming, { mergeObjects }) { return mergeObjects(existing, incoming); }, }, }, }, }, });
其他推荐答案
The other answers still work, but as of Apollo Client >= 3.3 there's an easier option that doesn't require specifying specific fields or a custom merge function. Instead, you only have to specify the type and it will merge all fields for that type:
const cache = new InMemoryCache({ typePolicies: { YOUR_TYPE_NAME: { merge: true, } } });
From your example query, I'd guess that an id field should be available though? Try requesting the ID in your query, that should solve the problem in a much more ideal way.