'How to use React Query's useQuery to fetch data with query params from an onSubmit function in a Formik form
I'm really new to React-Query so I an facing this issue. Here's the scenario. I have a component with a Formik form in it. It has a table with the list of data which is obtained from an initial GET request and a search form wrapped in a formik form that allows user to filter data. The user must click on filter once the search form is filled up to do another GET request which will then replace the data in the table.
One way I tried was to use the refetch function by passing in the parameters from the formik form but it doesn't work:
Here's my hook:
useTransactions.tsx
import { useQuery, useQueryClient } from 'react-query';
import { API } from "api";
interface ITransactionsData {
mobile?: string,
}
export const payload: ITransactionsData = {
mobile: '',
}
const getTransactions = (payload: ITransactionsData) => {
return API.get()('transactions', payload);
}
export const useTransactionListData = (payload: ITransactionListData) => {
return useQuery(
'transactions',
() => getTransactions(payload),
{
keepPreviousData: true,
}
)
}
Note that for the hook file above, I have a payload with mobile in it.This payload gets exported to the Form component and I do not wish to bind this to the useQuery as a variable since I only want the useQuery to be refetched when the user clicks on the search button. Also, I don not want to save this value with useState and use that as a variable in the useQuery since I'm already saving it in Formik's initialValues.
And here's my component: (payload is exported from the hooks file)
const Form = () => {
const { isLoading, isFetching, data: queryResult, isError, error, refetch} = useTransactionListData(payload);
const handleSearch = (values: any, { setSubmitting }: any) => {
//refetch();
refetch(values) <- I'm trying to pass in the values from formik to do a refetch with the new query params but it doesn't work...
}
return (
<Formik
initialValues={{
mobile: payload.mobile,
}}
onSubmit={handleSearch}
... (Formik Antd form here which holds a mobile number field).
setFieldValue will change the values.mobile
</Formik>
)
}
Is there a solution for this or should I consider using useMutation instead? Not sure if thats the proper way of doing things though and seems like I have to duplicate the useTransactionsListData function a similar version but using useMutation instead.
Solution 1:[1]
You'd have to make payload
part of the query key, as payload
is a "dependency" for your queryFn. react-query will always refetch automatically when the key changes:
export const useTransactionListData = (payload: ITransactionListData) => {
return useQuery(
['transactions', payload],
() => getTransactions(payload),
{
keepPreviousData: true,
}
)
}
This is documented:
keepPreviousData: true
will make sure that you'll see data from the previous key when the key changes to a new key - it does nothing with a static query key like 'transactions'
.
A good "storage" for the payload
would be the url
. You can write to the url when the user clicks the button, and then have your query subscribe via useParams
(if you are using react router). As a result, you'll get sharable urls for free.
Solution 2:[2]
I would try invalidating the query with the respective query key as shown here: https://react-query.tanstack.com/guides/query-invalidation
This will toggle a refresh.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | TkDodo |
Solution 2 | Lukas Germerott |