2

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

1 Answer 1

4

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

Sign up to request clarification or add additional context in comments.

1 Comment

thanks, this is exactly what I am looking for 😂 . Related to my question: stackoverflow.com/questions/76755482/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.