Apollo 客户端从缓存中删除项目
Posted
技术标签:
【中文标题】Apollo 客户端从缓存中删除项目【英文标题】:Apollo Client delete Item from cache 【发布时间】:2020-11-21 08:32:35 【问题描述】:我正在使用带有 React 的 Apollo 客户端。我用许多不同的变量查询帖子。所以我在不同的“缓存”中有一篇文章。现在我想删除一个帖子。所以我需要从所有“缓存”中删除这个特定的帖子。
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() ,结果相同。
感谢您的帮助。
【问题讨论】:
【参考方案1】:您可以将更新程序传递给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
链可能会帮助您。
【讨论】:
【参考方案2】:这个选项对我有用
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 (...);
;
【讨论】:
【参考方案3】:您可以使用cache.evict
,而不是使用cache.modify
,这使得代码更短:
deletePost(
variables: id ,
update(cache)
const normalizedId = cache.identify( id, __typename: 'Post' );
cache.evict( id: normalizedId );
cache.gc();
);
【讨论】:
这种情况下需要cache.gc()
吗?
我认为是的,apollographql.com/docs/react/caching/garbage-collection/… 说:“驱逐一个对象通常会使其他缓存的对象无法访问。因此,您应该在从缓存中驱逐一个或多个对象后调用 cache.gc。” 以上是关于Apollo 客户端从缓存中删除项目的主要内容,如果未能解决你的问题,请参考以下文章