React Router 6 Loaders with RTK Query #2751
-
Hello Redux community. Has anyone successfully implemented RTK Query data fetching with features like React Router loader (or Tanstack Router loader)? Should I manually initiate queries, access cache inside loader and return cached data there to use inside route component? Can I use manual cache retrieval in parallel with hooks, so the data stays up to date and independent from preloaded info?
The idea is to get initial set of information via loader and then work with hooks as is is intended (query and mutate data). I am afraid that if I preload data it will live in cache forever or immediately replaced by the data from hook or it will generated unnecessary http requests. Any ideas and advices are welcome. Thanks in advance |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 16 replies
-
None of us have tried it, but yes, that's what I've roughly imagined that you'd want to do. The data should stay in cache as long as specific components subscribe to those cache entries. |
Beta Was this translation helpful? Give feedback.
-
That said, you can also unwrap the result of initiate and should probably also unsubscribe the subscription that Also, it's probably an option to have the loader just initiate (and immediately unsubscibe after success) and use the hook in the component, which would at that point be prepopulated but also allows access to refetch etc. |
Beta Was this translation helpful? Give feedback.
-
https://codesandbox.io/s/rr6-4-rtk-auth-cdbtow |
Beta Was this translation helpful? Give feedback.
-
Would prefetching be a good solution to this? Seems to me like the main issue with dispatching the query withing the loader of react router is thst you have to get a bit tricky to properly unsubscribe or live with the fact that it won't get unsubscibed ever. I couldn't really find this information in the docs but the way I understood it is that prefetch would run the query and thus prime the cache WITHOUT adding a subscription. Thus making it a great fit for this loader scenario. |
Beta Was this translation helpful? Give feedback.
-
Hello! However in some situations I have a very annoying bug that I am not able to reproduce, and that is that loader is trigger, API calls made, data is ok, but my page doesn't re-render with the refreshed data.
I'm not sure what I am missing, but it doesn't seems to be a react-router issue, more a RTK Query one. Here is a simplified version of my loader: import { BaseLoader } from 'router/BaseLoader'
import { api } from 'services/api'
export class Loader extends BaseLoader {
detailLoader = async ({ params, request }) => {
const promises = [
this._loader(api.endpoints.fetchFullProfile, request),
this._loader(api.endpoints.fetchEntity, request, {
entity: 'rooms',
id: params.id
}),
this._loader(api.endpoints.fetchEntity, request, {
entity: 'activities',
id: params.id
}),
this._loader(api.endpoints.fetchEntity, request, {
entity: 'participants',
id: params.id
})
]
const [profile, rooms, activities, participants] =
await Promise.all([...promises])
return {
profile,
activities,
participants,
rooms
}
}
} Could you please help me or redirect me toward the right place to solve my problem? |
Beta Was this translation helpful? Give feedback.
-
There is another little downside with the dispatch(api.endpoints.getData.initiate()) approach in loader in combination with useQuery Hook to access the data. Edit: I will give https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#bailing-out-of-error-re-tries a try I think its good to use https://redux-toolkit.js.org/rtk-query/api/created-api/hooks#usequerystate instead of useQuery if you initiate fetching in react router loader functions. This helps wie duplicated error fetches. |
Beta Was this translation helpful? Give feedback.
-
Hi there, |
Beta Was this translation helpful? Give feedback.
That said, you can also unwrap the result of initiate and should probably also unsubscribe the subscription that
initiate
call creates.Also, it's probably an option to have the loader just initiate (and immediately unsubscibe after success) and use the hook in the component, which would at that point be prepopulated but also allows access to refetch etc.