-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Description
I'm experiencing an issue where if I apply an optimistic update when performing a mutation (slow POST endpoint) and a polling refetch (on a fast GET endpoint) occurs after the optimistic update but while the mutation is still in process, the optimistic update gets lost and the UI flickers back and forth.
Quick polling intervals (eg: 100) make this really easy to recreate.
The same issue (optimistic update gets lost) occurs on "refetch on focus" as well.
Ideas on possible solutions (none of which have worked):
- Wrap the query hook at a global level and use
skipif mutation is in progress. Unfortunately this doesn't work. The optimistic update doesn't become visible in any part of the application using the hook whenskipis true.
export const getCampaignsApi = (state: State) => state.campaignsApi
export const getMutationInProgress = createSelector([getCampaignsApi], campaignsApi => {
return Object.values(campaignsApi.mutations).some(mutation => mutation?.status === 'pending')
})
export function useGetAllCampaignMetadataQuery(options?: UseQueryOptions) {
const mutationInProgress = useSelector(getMutationInProgress)
return campaignApiSlice.useGetAllCampaignMetadataQuery(undefined, {
skip: mutationInProgress,
...options
})
}- Try using the
mergefunctionality. Unfortunately an error is thrown if I try to usestore.getState()it within themergefunction.getStateis not exposed in themergecallback so I would have no other way of accessing the current state.
export function getMutationInProgress() { {
const state = store.getState()
return Object.values(campaignsApi.mutations).some(mutation => mutation?.status === 'pending')
}
getAllCampaigns: builder.query({
// other parts of endpoint definition omitted
merge: (currentCacheData, responseData) => {
const mutationInProgress = getMutationInProgress()
if (mutationInProgress) {
return currentCacheData
}
else {
return responseData
}
})Video Screenshots
Polling
https://github.com/user-attachments/assets/7627e4c4-3460-480c-9db8-0c6003a96bcf
Refetch on focus
https://github.com/user-attachments/assets/cd9557ad-5559-464b-82ce-4640673c9fbc
Minimal reproduction
Unfortunately i'm not able to set up a fully working example due to the fact that a simple mock server that serves the same mock response every time wouldn't be able to save the changes of a mutation (since I would need a proper database to do so). The real endpoints i'm using on my project require authentication. That being said, here is the stripped down code I used for my video example:
https://github.com/agusterodin/rtkq-playground/tree/optimistic-update-polling-race-condition
To run this use pnpm i and pnpm dev. I have the polling and refetch on focus lines commented out but had them uncommented when taking their respective video screenshots.