Skip to main content

What problem does this solve?

Handling the loading and error state of components that depend on external data can be tedious, especially when you are managing multiple queries.


This component requires some data. There are 26 lines of code that are just concerned with ensuring that the data is present before rendering the actual component.

const Component = () => {
const pokemonQuery = useGetPokemon("charizard");
const userQuery = useGetCurrentUser();
const userStatsQuery = useGetUserStats();

if (
pokemonQuery.isLoading ||
userQuery.isLoading ||
) {
return <LoadingView />;

if (
pokemonQuery.isError ||
userQuery.isError ||
) {
return (
pokemonQuery.error ??
userQuery.error ??
// Finally...
return (

RTK Query Loader lets you move all of this logic out of the component, and also make it reusable and composable, so that other components can reuse that loader and have access to the same data.

  • Isolate the data-loading code away from the presentational components
  • Increase type certainty
    • 🔥 Way less optional chaining in your components
    • 🔥 You write the components as if the data is already present
  • Composability
    • ♻️ Extend existing loaders
    • ♻️ Overwrite only select properties
  • You're still fully in control
    • 🛠️ Loading/error states
    • 🛠️ Custom loader-component
    • 🛠️ Configure the behavior of your loaders


Terminology explaination


If you are using a Suspense-enabled framework, or any form of server-side rendering that can feed your components with data, then that would be a more optimal approach. Remix has the concept of loaders built in, and NextJS is suspense enabled.

If you are, however, building an SPA, or not using Next or Remix, then this package can be a great way for you gain the concept of loaders without moving to server-side rendering.