I'm trying to query
data from an end point with different params based on button click event.
I used the code splitting method by rtk query and created the base service as
import { createApi } from "@reduxjs/toolkit/query/react";
import { axiosBaseQuery } from "./util";
export const appApi = createApi({
baseQuery: axiosBaseQuery({
baseUrl: `https://baseurl`,
}),
refetchOnReconnect: true,
endpoints: () => ({}),
});
and inject endpoint like
import { appApi } from "./appApi";
export const popupAPI = appApi.injectEndpoints({
endpoints: (builder) => ({
getPopupData: builder.query<
any,
{
id: string;
startDate: string | Date | null;
endDate: string | Date | null;
}
>({
query: (params) => {
const { id, startDate, endDate } = params;
return {
url: `kpi/?id=${id}&startdate=${startDate}&enddate=${endDate}`,
};
},
}),
}),
overrideExisting: true,
});
export const { useGetPopupDataQuery } = popupAPI;
In the component file the start date
is set initially and changes on button click.
const startDate = moment()
.subtract(selectedDays || 1, "days")
.format("YYYY-MM-DD");
const endDate = moment()
.subtract(1, "days")
.format("YYYY-MM-DD");
The selectedDays
is initially set to 1
and changes to 2, 3, etc on button click. I subscribe to the data and other variables like
const {
data,
isLoading,
error,
} = useGetPopupDataQuery({
id
startDate: startDate,
endDate: endDate,
});
On the first time, when component mounts the values of isLoading
, data
and error
are set accordingly and when the data fetch completed the isLoading
is set to false and data
with data. But the issue is when I click the button the selectedDays
changes and an API call is send. But the previous data
isLoading
error
are not changed/reset. So I'm not able to show the loading/intermediate stage. The after the data fetch completes when inspected the data
variable is filled with new data. I'm trying to resolve this issue and any help/suggestions would be really helpful.
The isLoading
flag is used when the query is being initially made and there are no previous requests cached in the store. You might be looking to use the isFetching
flag instead of, or in addition to, isLoading
. The data
will simply be the cached data from the previous successful request.
See useQuery
type UseQueryResult<T> = { // Base query state ... // Derived request status booleans isUninitialized: boolean // Query has not started yet. isLoading: boolean // Query is currently loading for the first time. No data yet. isFetching: boolean // Query is currently fetching, but might have data from an earlier request. isSuccess: boolean // Query has data from a successful load. isError: boolean // Query is currently in an "error" state. refetch: () => void // A function to force refetch the query }
Here's an example I use for handling subsequent requests.
const {
data,
isLoading as popupDataIsLoading,
isFetching as pPopupDataIsFetching,
error,
} = useGetPopupDataQuery({
id
startDate: startDate,
endDate: endDate,
});
const isLoading = popupDataIsLoading || pPopupDataIsFetching;
Here you can apply any conditional logic when the query is either being loaded for the first time or an active request is pending.
I wouldn't recommend it, but if you are looking for a "nuclear" option then there also exists resetApiState
.
Signature
const resetApiState = () => ({ type: string, payload: undefined, })
Description A Redux action creator that can be dispatched to manually reset the api state completely. This will immediately remove all existing cache entries, and all queries will be considered 'uninitialized'.
Note that hooks also track state in local component state and might not fully be reset by resetApiState.
Example
dispatch(api.util.resetApiState())
This resets the entire API state and may very likely be too blunt a tool though. Use with caution.