I have an RTK Query mutation endpoint rejectApplication, that invalidates the getApplication query. These are in the same API.
rejectApplication: builder.mutation<RejectResponse, string>({
query: (applicationId) => ({
url: `/applications/${applicationId}`,
method: "DELETE",
}),
invalidatesTags: (_result, _error, applicationId) => [
"Status",
{ type: "Application", id: "LIST" },
{ type: "Application", id: applicationId },
],
}),
getApplication: builder.query<ApplicationResponse, string>({
query: (applicationId: string) => ({
method: "GET",
url: `/applications/${applicationId}`,
}),
providesTags: (_result, _error, id) => [{ type: "Application", id: id }],
}),
Problem is that I have two components that use the useRejectApplicationMutation hook, but for some reason only one of them seems to correctly remove the query result from cache after it has been invalidated. I can observe this through the Redux devtools, where I can see the removeQueryResult actions being dispatched after the reject mutation has fulfilled in one component, but not firing in the other component. This leads to the getApplication data in the component not changing, which breaks the flow of the application.
const {
data,
isLoading: getApplicationIsLoading,
isError: getApplicationIsError,
} = useGetApplicationQuery(props.application.applicationId as string);
useEffect(() => {
if (data) {
dispatch(setIncompleteApplication(data));
}
}, [data]);
So in this case, the useEffect with data is not called because data doesn't seem to be refetched, although it should be invalidated after reject mutation is fulfilled. Weirdly, in the console it does look like it should be correctly refetching the application and status which are invalidated, as the MSW endpoints are hit after the delete request.
[MSW] 12:37:38 DELETE /v1/applications/XA1234567 (200 OK)
[MSW] 12:37:38 GET /v1/status (200 OK)
[MSW] 12:37:39 GET /v1/applications/XA1234567 (200 OK)
To me, the problem seems to be that the cache isn't properly cleared for some reason, so although the tags are invalidated and refetches made the data isn't properly reset. Any ideas to what might be causing this inconsistancy?
invalidatesTags
does not always remove things from cache. It only removes things from cache for cache entries that are not being used in a component at the moment - for everything else it triggers a refetch, so the request is fired off again and if there is new data in the response, the response is updated accordingly.
So in your component, isFetching
will switch to true
, but the data will not disappear - in most cases that is the preferred behaviour, as you don't want everything to jump to a loading indicator, but just update displayed data after a mutation.
Now, if your endpoint returns data that is structurally equal to the data it returned before, it will also not be a new data
object, but just the old one. On a refetch, RTK-Query compares the old and new result and tries to keep as much of it referentially equal as possible, so useEffects
are not fired off when the underlying data did actually not change at all.