【问题标题】:Apollo Mutation - UI not updated after useMutation updateApollo Mutation - 在 useMutation 更新后 UI 未更新
【发布时间】:2020-07-26 10:31:04
【问题描述】:

背景:总是可以更新 Apollo 存储缓存,但不能更新 UI

问题:

  1. UI 更新与否的原因是什么?
  2. 在更新中传递数据对象的正确方法是什么?

“反应”:“~16.9.0”

"@apollo/react-hooks": "^3.1.3"

我的项目中的 UI 和缓存更新代码:

update: (store, { data: { newPhoto } }) => {
  const { bookInfo } = store.readQuery({ query: GET_BOOK_BY_ID, variables: { bookId } });
  bookInfo.photos = [...bookInfo.photos, newPhoto];

  store.writeQuery({ 
      query: GET_BOOK_BY_ID, 
      variables: { bookId },
      data: {
          bookInfo
      }
  });
}

在这一行:bookInfo.photos = [...bookInfo.photos, newPhoto];,直接修改bookInfo对象,直接传回writeQuerydata

这对我来说看起来不太好,因为我看到人们说它需要是“不可变的”或“传递新对象”等。

【问题讨论】:

  • 我认为,您的组件渲染功能内部的查询部分可能存在问题。请分享您的查询部分代码,尤其是您使用查询的方式和变量。变量部分应该与你变异的部分完全相同
  • 嗨@TrueEye!感谢您的评论。我已经解决了这个问题,因为我没有以不可变的方式编辑数据!有同样经历的人,一定要去看看github.com/apollographql/apollo-client/pull/4543。通过将 freezeResults 和 assumeImmutableResults 应用到 Apollo 客户端将有助于检测问题。

标签: reactjs apollo react-apollo


【解决方案1】:

如果您遇到同样的事情,请查看以下列表:

  1. 去看看https://github.com/apollographql/apollo-client/pull/4543。通过将freezeResultsassumeImmutableResults 应用到ApolloClient 将有助于检测问题。就我而言,问题实际上发生在父组件内部,我改变了 Apollo 存储对象,而不是调用 client.writeQuery 的组件,在我看来,其他人通常也很难注意到。
const client = new ApolloClient({
  link: ...,
  cache: new InMemoryCache({
    freezeResults: true, // new
  }),
  assumeImmutableResults: true, // new
});
  1. 确保以不可变的方式改变数据。 (即 Apollo 存储对象直到更新结束才更改)https://github.com/immerjs/immer 绝对有助于以不可变的方式保持您的更改。我用它来改变我的嵌套对象,它工作得很好。
  2. 尝试使用从useMutation返回的client,然后你会得到client.writeQuery进行更新。虽然我不确定这一点,但很多人传播此信息,在某些情况下可能会有所帮助。
import { useMutation } from '@apollo/react-hooks';
import produce from "immer";

const [mutate, { client }] = useMutation(MUTATION_GQL);

const submit = () => {
    mutate({
        variables: { inputs },
        update: (store, { data: { response }) => {
            // get existing cache returned from the query
            const cache = store.readQuery({ query: QUERY_GQL, variables: { id } });

            // manipulate the cache in immutable fashion
            const data = produce(cache, draftCache => {
                draftCache.title = "new title";
                draftCache.approval = response;
            });

            // write the cache back to that query
            // REMEMBER the variables inside writeQuery too!
            client.writeQuery({
                query: QUERY_GQL,
                variables: { id },
                data,
            });
        }
    })
}
  1. 尝试使用useQueryApolloClient而不是readQuery读取数据,这样您就可以从Apollo的存储中获取更新的缓存

【讨论】:

    猜你喜欢
    • 2019-04-27
    • 2020-06-04
    • 2017-11-02
    • 2018-07-15
    • 2020-05-09
    • 2022-11-13
    • 2018-02-07
    • 1970-01-01
    • 2015-10-22
    相关资源
    最近更新 更多