Apollo客户端从缓存中删除项目

时间:2020-07-31 13:27:02

标签: reactjs apollo-client

为什么我将Apollo Client与React一起使用。我用许多不同的变量查询帖子。因此,我在不同的“缓存”中发表了一篇文章。现在我要删除帖子。因此,我需要从所有“缓存”中删除此特定帖子。

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])< / p>

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(),结果相同。

THX以寻求帮助。

3 个答案:

答案 0 :(得分:8)

您可以使用 cache.modify 代替 cache.evict,这使得代码更短:

deletePost({
    variables: { id },
    update(cache) {
        const normalizedId = cache.identify({ id, __typename: 'Post' });
        cache.evict({ id: normalizedId });
        cache.gc();
    }
});

答案 1 :(得分:5)

此选项对我有用

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 (...);
};

答案 2 :(得分:2)

您可以将更新程序传递给useMutationdeletePost。使用deletePost应该更容易,因为它可能知道它尝试删除的内容:

    deletePost({
        variables: { idToRemove },
        update(cache) {
            cache.modify({
                fields: {
                    posts(existingPosts = []) {
                        return existingPosts.filter(
                            postRef => idToRemove !== readField('id', postRef)
                        );
                    },
                },
            });
        },
    });

您应该更改variables以匹配您的突变。这应该可行,因为posts在查询的顶层。对于更深的字段,您将需要一种获取父对象的ID的方法。 readQuery或顶部的readField链可能会帮助您。