Apollo 客户端从缓存中删除项目
Apollo Client delete Item from cache
嗨,我正在使用带有 React 的 Apollo 客户端。我用许多不同的变量查询 posts。所以我在不同的“缓存”中有一个 post。现在我想删除一个post。所以我需要从所有“缓存”中删除这个特定的 post。
const client = new ApolloClient({
link: errorLink.concat(authLink.concat(httpLink)),
cache: new InMemoryCache()
});
后查询:
export const POSTS = gql`
query posts(
$after: String
$orderBy: PostOrderByInput
$tags: JSONObject
$search: String
$orderByTime: Int
) {
posts(
after: $after
orderBy: $orderBy
tags: $tags
search: $search
orderByTime: $orderByTime
) {
id
title
...
}
}
`;
我用 cache.modify() 试过了,它在我的突变中是未定义的([https://www.apollographql.com/docs/react/caching/cache-interaction/#cachemodify][1])
const [deletePost] = useMutation(DELETE_POST, {
onError: (er) => {
console.log(er);
},
update(cache, data) {
console.log(cache.modify())//UNDEFINED!!!
cache.modify({
id: cache.identify(thread), //identify is UNDEFINED + what is thread
fields: {
posts(existingPosts = []) {
return existingPosts.filter(
postRef => idToRemove !== readField('id', postRef)
);
}
}
})
}
});
我也使用了 useApolloClient() 得到了相同的结果。
感谢任何帮助。
您可以将更新程序传递给 useMutation
或 deletePost
。使用 deletePost
应该更容易,因为它可能知道要删除的内容:
deletePost({
variables: { idToRemove },
update(cache) {
cache.modify({
fields: {
posts(existingPosts = []) {
return existingPosts.filter(
postRef => idToRemove !== readField('id', postRef)
);
},
},
});
},
});
您应该更改 variables
以匹配您的突变。这应该有效,因为 posts
位于查询的顶层。对于更深的字段,您将需要一种方法来获取父对象的 ID。 readQuery
或顶部的一系列 readField
可能会帮助您。
这个选项对我有用
const GET_TASKS = gql`
query tasks($listID: String!) {
tasks(listID: $listID) {
_id
title
sort
}
}
`;
const REMOVE_TASK = gql`
mutation removeTask($_id: String) {
removeTask(_id: $_id) {
_id
}
}
`;
const Tasks = () => {
const { loading, error, data } = useQuery(GET_TASKS, {
variables: { listID: '1' },
});
сonst [removeTask] = useMutation(REMOVE_TASK);
const handleRemoveItem = _id => {
removeTask({
variables: { _id },
update(cache) {
cache.modify({
fields: {
tasks(existingTaskRefs, { readField }) {
return existingTaskRefs.filter(
taskRef => _id !== readField('_id', taskRef),
);
},
},
});
},
});
};
return (...);
};
您可以使用 cache.evict
而不是使用 cache.modify
,这会使代码更短:
deletePost({
variables: { id },
update(cache) {
const normalizedId = cache.identify({ id, __typename: 'Post' });
cache.evict({ id: normalizedId });
cache.gc();
}
});
嗨,我正在使用带有 React 的 Apollo 客户端。我用许多不同的变量查询 posts。所以我在不同的“缓存”中有一个 post。现在我想删除一个post。所以我需要从所有“缓存”中删除这个特定的 post。
const client = new ApolloClient({
link: errorLink.concat(authLink.concat(httpLink)),
cache: new InMemoryCache()
});
后查询:
export const POSTS = gql`
query posts(
$after: String
$orderBy: PostOrderByInput
$tags: JSONObject
$search: String
$orderByTime: Int
) {
posts(
after: $after
orderBy: $orderBy
tags: $tags
search: $search
orderByTime: $orderByTime
) {
id
title
...
}
}
`;
我用 cache.modify() 试过了,它在我的突变中是未定义的([https://www.apollographql.com/docs/react/caching/cache-interaction/#cachemodify][1])
const [deletePost] = useMutation(DELETE_POST, {
onError: (er) => {
console.log(er);
},
update(cache, data) {
console.log(cache.modify())//UNDEFINED!!!
cache.modify({
id: cache.identify(thread), //identify is UNDEFINED + what is thread
fields: {
posts(existingPosts = []) {
return existingPosts.filter(
postRef => idToRemove !== readField('id', postRef)
);
}
}
})
}
});
我也使用了 useApolloClient() 得到了相同的结果。
感谢任何帮助。
您可以将更新程序传递给 useMutation
或 deletePost
。使用 deletePost
应该更容易,因为它可能知道要删除的内容:
deletePost({
variables: { idToRemove },
update(cache) {
cache.modify({
fields: {
posts(existingPosts = []) {
return existingPosts.filter(
postRef => idToRemove !== readField('id', postRef)
);
},
},
});
},
});
您应该更改 variables
以匹配您的突变。这应该有效,因为 posts
位于查询的顶层。对于更深的字段,您将需要一种方法来获取父对象的 ID。 readQuery
或顶部的一系列 readField
可能会帮助您。
这个选项对我有用
const GET_TASKS = gql`
query tasks($listID: String!) {
tasks(listID: $listID) {
_id
title
sort
}
}
`;
const REMOVE_TASK = gql`
mutation removeTask($_id: String) {
removeTask(_id: $_id) {
_id
}
}
`;
const Tasks = () => {
const { loading, error, data } = useQuery(GET_TASKS, {
variables: { listID: '1' },
});
сonst [removeTask] = useMutation(REMOVE_TASK);
const handleRemoveItem = _id => {
removeTask({
variables: { _id },
update(cache) {
cache.modify({
fields: {
tasks(existingTaskRefs, { readField }) {
return existingTaskRefs.filter(
taskRef => _id !== readField('_id', taskRef),
);
},
},
});
},
});
};
return (...);
};
您可以使用 cache.evict
而不是使用 cache.modify
,这会使代码更短:
deletePost({
variables: { id },
update(cache) {
const normalizedId = cache.identify({ id, __typename: 'Post' });
cache.evict({ id: normalizedId });
cache.gc();
}
});