问题描述
我不确定自己在做什么错,因为一切正常,但是每次运行DELETE_PHOTO
突变时,我都会收到此讨厌的错误消息:
替换用户的照片字段时,缓存数据可能会丢失 对象。
我有User对象,其中包含照片列表:
email: "test@test.fi"
fullname: "Test user"
id: "5f058ca0bf08318028019059"
isAdmin: true
photos:
0:{"__ref":"Photo:5f44b37892f7b011ec491f25"}
1:{"__ref":"Photo:5f44b37a92f7b011ec491f26"}
2:{"__ref":"Photo:5f44b37d92f7b011ec491f27"}
3:{"__ref":"Photo:5f44b38192f7b011ec491f28"}
4:{"__ref":"Photo:5f44b38792f7b011ec491f2a"}
5:{"__ref":"Photo:5f44b38992f7b011ec491f2b"}
6:{"__ref":"Photo:5f44b38c92f7b011ec491f2c"}
7:{"__ref":"Photo:5f44b38e92f7b011ec491f2d"}
8:{"__ref":"Photo:5f44b39092f7b011ec491f2e"}
9:{"__ref":"Photo:5f44b39292f7b011ec491f2f"}
10:{"__ref":"Photo:5f44b39492f7b011ec491f30"}
11:{"__ref":"Photo:5f44b39892f7b011ec491f31"}
12:{"__ref":"Photo:5f44b39a92f7b011ec491f32"}
13:{"__ref":"Photo:5f44b39d92f7b011ec491f33"}
14:{"__ref":"Photo:5f44b3a092f7b011ec491f34"}
15:{"__ref":"Photo:5f44b3a492f7b011ec491f35"}
16:{"__ref":"Photo:5f44b3a792f7b011ec491f36"}
17:{"__ref":"Photo:5f44b3aa92f7b011ec491f37"}
18:{"__ref":"Photo:5f44b3ad92f7b011ec491f38"}
19:{"__ref":"Photo:5f44b3af92f7b011ec491f39"}
20:{"__ref":"Photo:5f44b3b292f7b011ec491f3a"}
21:{"__ref":"Photo:5f44b3b592f7b011ec491f3b"}
22:{"__ref":"Photo:5f44c5e192f7b011ec491f3c"}
23:{"__ref":"Photo:5f453f1e479a7649e8191a04"}
username: "admin"
每个照片对象都是这样的:
dateAdded: "1598337912783"
description: null
filename: "images/851ca650-e69e-11ea-bdf1-eb9595fbd23e"
id: "5f44b37892f7b011ec491f25"
mainUrl: "https://firebasestorage.googleapis.com/..."
name: "2013-07-27 12-25-40 1479 (Canon EOS 40D)"
originalFilename: "2013-07-27 12-25-40 1479 (Canon EOS 40D).jpg"
thumbFilename: "images/851ca651-e69e-11ea-bdf1-eb9595fbd23e"
thumbUrl: "https://firebasestorage.googleapis.com/..."
export const ME = gql`
query me {
me {
username,email,fullname,isAdmin,photos {
mainUrl,thumbUrl,filename,thumbFilename,originalFilename,name,description,dateAdded,id
},id
}
}
`;
删除照片的突变是:
export const DELETE_PHOTO = gql`
mutation deletePhoto(
$id: ID!
) {
deletePhoto(
id: $id
) {
mainUrl,id
}
}
`;
当我执行DELETE_PHOTO
查询时,我得到有关已删除照片的对象作为响应:
deletePhoto:
dateAdded: "1598337912783"
description: null
filename: "images/851ca650-e69e-11ea-bdf1-eb9595fbd23e"
id: "5f44b37892f7b011ec491f25"
mainUrl: "https://firebasestorage.googleapis.com/..."
name: "2013-07-27 12-25-40 1479 (Canon EOS 40D)"
originalFilename: "2013-07-27 12-25-40 1479 (Canon EOS 40D).jpg"
thumbFilename: "images/851ca651-e69e-11ea-bdf1-eb9595fbd23e"
thumbUrl: "https://firebasestorage.googleapis.com/..."
__typename: "Photo"
然后,我使用以下代码通过从用户对象的照片数组中删除该项目来更新Apollo缓存:
const [deletePhotoFromDb] = useMutation(DELETE_PHOTO,{
update: (cache,response) => {
const existingCache = cache.readQuery({ query: ME });
if (existingCache) {
const idToDelete = response.data.deletePhoto.id;
const updatedPhotos = existingCache.me.photos.filter(p => p.id !== idToDelete);
const updatedCache = {
...existingCache,me: {
...existingCache.me,photos: updatedPhotos
}
};
cache.writeQuery({
query: ME,data: updatedCache
});
}
}
});
更新缓存有效,因为照片将立即从React的UI中删除。如果不更新缓存,则不会从UI中删除照片。
Cache data may be lost when replacing the photos field of a User object.
To address this problem (which is not a bug in Apollo Client),define a custom merge function for the User.photos field,so InMemoryCache can safely merge these objects:
existing: [{"__ref":"Photo:5f44b37a92f7b011ec491f26"},{"__ref":"Photo:5f44b37d92f7b011ec491f27"},{"__ref":"Photo:5f44b38192f7b011ec491f28"},{"__ref":"Photo:5f44b38792f7b011ec491f2a"},{"__ref":"Photo:5f44b38992f7b011ec491f2b"},{"__ref":"Photo:5f44b38c92f7b011ec491f2c"},{"__ref":"Photo:5f44b38e92f7b011ec491f2d"},{"__ref":"Photo:5f44b39092f7b011ec491f2e"},{"__ref":"Photo:5f44b39292f7b011ec491f2f"},{"__ref":"Photo:5f44b39492f7b011ec491f30"},{"__ref":"Photo:5f44b39892f7b011ec491f31"},{"__ref":"Photo:5f44b39a92f7b011ec491f32"},{"__ref":"Photo:5f44b39d92f7b011ec491f33"},{"__ref":"Photo:5f44b3a092f7b011ec491f34"},{"__ref":"Photo:5f44b3a492f7b011ec491f35"},{"__ref":"Photo:5f44b3a792f7b011ec491f36"},{"__ref":"Photo:5f44b3aa92f7b011ec491f37"},{"__ref":"Photo:5f44b3ad92f7b011ec491f38"},{"__ref":"Photo:5f44b3af92f7b011ec491f39"},{"__ref":"Photo:5f44b3b292f7b011ec491f3a"},{"__ref":"Photo:5f44b3b592f7b011ec491f3b"},{"__ref":"Photo:5f44c5e192f7b011ec491f3c"},{"__ref":"Photo:5f453f1e479a7649e8191a04"}]
incoming: [{"__ref":"Photo:5f44b37a92f7b011ec491f26"},{"__ref":"Photo:5f44c5e192f7b011ec491f3c"}]
解决方法
感谢 xadm 将我指向正确的评论方向。
我将空的InMemoryCache对象替换为以下内容,并且不再显示警告消息:
const cache = new InMemoryCache({
typePolicies: {
User: {
fields: {
photos: {
merge(existing = [],incoming: any[]) {
return [...incoming];
}
}
}
}
}
});