Currently, I am using Tanstack Query V5 in my vite-react project.
Whenever I try to use invalidateQueries
it throws an error TypeError: Cannot read from private field
I want is, when the mutation for invoice deletion will trigger it refetch the invoice list again
main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter as Router } from 'react-router-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { ReactQueryDevtools } from '@tanstack/react-query-devtools'
const queryClient = new QueryClient()
import App from './App.tsx'
import { DashboardProvider } from './context/Dashboard.context'
import { Toaster } from '@/components/ui/toaster'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<Router>
<QueryClientProvider client={queryClient}>
<DashboardProvider>
<App />
<Toaster />
</DashboardProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</Router>
</React.StrictMode>
)
Here is my code for useQuery
const { isFetching, data } = useQuery({
queryKey: ['invoiceList', page, limit],
queryFn: async () => {
const { data } = await apiRequest.get('/client/invoiceList', {
params: { page, limit },
})
return data
},
})
Here is my code for useMutation & invalidateQueries
const { invalidateQueries } = useQueryClient()
const { mutate, isPending } = useMutation({
mutationFn: async () => {
return await apiRequest.delete('/client/deleteInvoice', {
params: { id: invoice?.id },
})
},
onSuccess: () => {
toast({
variant: 'success',
title: 'Invoice deleted successfully',
description: `Invoice ${invoice?.reference} has been deleted successfully`,
})
invalidateQueries({ queryKey: ['invoiceList'] })
},
onError: (error) => {
console.log(error?.message)
handleError(error, toast)
},
})
Here is the complete error -
TypeError: Cannot read from private field
at __accessCheck (chunk-TIUEEL27.js?v=ae984db9:41:11)
at __privateGet (chunk-TIUEEL27.js?v=ae984db9:44:3)
at chunk-PF574KJM.js?v=ae984db9:1620:7
at Object.batch (chunk-PF574KJM.js?v=ae984db9:499:16)
at invalidateQueries (chunk-PF574KJM.js?v=ae984db9:1619:26)
at onClick (index.tsx:81:15)
at HTMLUnknownElement.callCallback2 (chunk-EL3PUDHE.js?v=ae984db9:3674:22)
at Object.invokeGuardedCallbackDev (chunk-EL3PUDHE.js?v=ae984db9:3699:24)
at invokeGuardedCallback (chunk-EL3PUDHE.js?v=ae984db9:3733:39)
at invokeGuardedCallbackAndCatchFirstError (chunk-EL3PUDHE.js?v=ae984db9:3736:33)
Initially, I thought this error was occurring for the version. So I update the version from 5.14.2 to ^5.26.3. But the problem remains unsolved.
The queryClient
you get from useQueryClient
is an instance of the class QueryClient
that uses private fields, simplified example:
class QueryClient {
#foo = 'bar'
invalidateQueries() {
return this.#foo
}
}
const queryClient = new QueryClient()
If you destructure queryClient
like so
const { invalidateQueries } = queryClient
you are losing the context of the function, so when you call it, you're calling it without access to this.#foo
:
invalidateQueries() // throws an error
// but this keeps working
queryClient.invalidateQueries() // 'bar'
This is expected behaviour of JS with regards to context (the value of this
).
--
The solution for you is to not destructure:
const queryClient = useQueryClient()
queryClient.invalidateQueries()