使用 React Query 进行突变后更新缓存中的多个键

发布于 2025-01-18 19:18:59 字数 1352 浏览 1 评论 0原文

我正在使用 React Query,我想在突变后更新缓存,但我想一次性更新多个键。

我有 "invoices"["invoice", 1],我按如下方式更新它:

queryClient.setQueryData("invoices", ({invoices}) => {
    return {
        invoices: [
            ...filter(invoices, invoice => invoice.id !== activeInvoice),
            {
                ...find(invoices, invoice => invoice.id === activeInvoice),
                customer: data?.updateInvoiceCustomer?.customer
            }
        ]
    }
})

queryClient.setQueryData(["invoice", activeInvoice], ({invoice}) => {
    return {
        invoice: {
            ...invoice,
            customer: data?.updateInvoiceCustomer?.customer
        }
    }
})

因此,现在我按每个键执行此操作。有没有办法一次性完成并使用这样的东西:

queryClient.setQueriesData(["invoices", ["invoice", activeInvoice]], ({invoices, invoice}) => {
    return {
        invoices: [
            ...filter(invoices, invoice => invoice.id !== activeInvoice),
            {
                ...find(invoices, invoice => invoice.id === activeInvoice),
                customer: data?.updateInvoiceCustomer?.customer
            }
        ],
        invoice: {
            invoice: {
                ...invoice,
                customer: data?.updateInvoiceCustomer?.customer
            }

        }
    }
})

谢谢

I'm using React Query and I want to update cache after the mutation, but I want to update multiple keys in one go.

I have "invoices" and ["invoice", 1] and I update it as follows:

queryClient.setQueryData("invoices", ({invoices}) => {
    return {
        invoices: [
            ...filter(invoices, invoice => invoice.id !== activeInvoice),
            {
                ...find(invoices, invoice => invoice.id === activeInvoice),
                customer: data?.updateInvoiceCustomer?.customer
            }
        ]
    }
})

queryClient.setQueryData(["invoice", activeInvoice], ({invoice}) => {
    return {
        invoice: {
            ...invoice,
            customer: data?.updateInvoiceCustomer?.customer
        }
    }
})

Thus, now I do it per key. Is there any way to do it in one go and to use something like this:

queryClient.setQueriesData(["invoices", ["invoice", activeInvoice]], ({invoices, invoice}) => {
    return {
        invoices: [
            ...filter(invoices, invoice => invoice.id !== activeInvoice),
            {
                ...find(invoices, invoice => invoice.id === activeInvoice),
                customer: data?.updateInvoiceCustomer?.customer
            }
        ],
        invoice: {
            invoice: {
                ...invoice,
                customer: data?.updateInvoiceCustomer?.customer
            }

        }
    }
})

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

再见回来 2025-01-25 19:18:59

选择两个查询的API有些不同。

第一个选项,您必须将键更改为['Invoices'] and ['Invoices',ID],然后您可以“部分匹配”,只需通过提供['Invoices'] setqueriesdata 。

但是即使到那时,您也必须检查更新程序中的哪一个:

queryClient.setQueriesData(["invoices"], (data) => {
  if (Array.isArray(data)) {
    // updating the list
  } else {
    // updating the resource
    if (data.id === id) {
      // the filter matches not only ['invoices', id] but all ids
    }
  }
})

老实说,它看起来并不是很符合人体工程学。

第二种选择,您也可以使用谓词使其更可读性,

queryClient.setQueriesData({
  predicate: function ({ queryKey }) {
    if (queryKey[0] === 'invoices') {
      return true
    }
    if (queryKey[0] === 'invoice' && queryKey[1] === id) {
      return true
    }
    return false
  }
}, (data) => {
  if (Array.isArray(data)) {
    // updating the list
  } else {
    // updating the resource
  }
})

但说实话,您的原始代码仍然对我来说更读

The API is a bit different, to select both queries.

First option, you would have to change the keys to be ['invoices'] and ['invoices', id], then you can "match them partially", just by providing ['invoices'] to setQueriesData.

But even then you would have to check which one is which inside the updater:

queryClient.setQueriesData(["invoices"], (data) => {
  if (Array.isArray(data)) {
    // updating the list
  } else {
    // updating the resource
    if (data.id === id) {
      // the filter matches not only ['invoices', id] but all ids
    }
  }
})

To be honest, it doesn't look very ergonomic.

Second option, you can make it a bit more readable by using a predicate as well instead

queryClient.setQueriesData({
  predicate: function ({ queryKey }) {
    if (queryKey[0] === 'invoices') {
      return true
    }
    if (queryKey[0] === 'invoice' && queryKey[1] === id) {
      return true
    }
    return false
  }
}, (data) => {
  if (Array.isArray(data)) {
    // updating the list
  } else {
    // updating the resource
  }
})

But to be honest, your original code still looks more readble to me

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文