Skip to content

ryfylke-react-as/rtk-query-loader

Repository files navigation

@ryfylke-react/rtk-query-loader

npm npm type definitions npm bundle size

Lets you create loaders that contain multiple RTK queries.

Usage

yarn add @ryfylke-react/rtk-query-loader
# or
npm i @ryfylke-react/rtk-query-loader

A simple example of a component using rtk-query-loader:

import {
  createLoader,
  withLoader,
} from "@ryfylke-react/rtk-query-loader";

const loader = createLoader({
  useQueries: () => {
    const pokemon = useGetPokemon();
    const currentUser = useGetCurrentUser();

    return {
      queries: {
        pokemon,
        currentUser,
      },
    };
  },
  onLoading: () => <div>Loading pokemon...</div>,
});

const Pokemon = withLoader((props, loader) => {
  const pokemon = loader.queries.pokemon.data;
  const currentUser = loader.queries.currentUser.data;

  return (
    <div>
      <h2>{pokemon.name}</h2>
      <img src={pokemon.image} />
      <a href={`/users/${currentUser.id}/pokemon`}>
        Your pokemon
      </a>
    </div>
  );
}, loader);

What problem does this solve?

Let's say you have a component that depends on data from more than one query.

function Component(props){
  const userQuery = useGetUser(props.id);
  const postsQuery = userGetPostsByUser(userQuery.data?.id, {
    skip: user?.data?.id === undefined,
  });

  if (userQuery.isError || postsQuery.isError){
    // handle error
  }

  /* possible something like */
  // if (userQuery.isLoading){ return (...) }

  return (
    <div>
      {/* or checking if the type is undefined in the jsx */}
      {(userQuery.isLoading || postsQuery.isLoading) && (...)}
      {userQuery.data && postsQuery.data && (...)}
    </div>
  )
}

The end result is possibly lots of bloated code that has to take into consideration that the values could be undefined, optional chaining, etc...

What if we could instead "join" these queries into one, and then just return early if we are in the initial loading stage. That's basically the approach that rtk-query-loader takes. Some pros include:

  • Way less optional chaining in your components
  • Better type certainty
  • Easy to write re-usable loaders that can be abstracted away from the components