Examples
This page contains a collection of examples that cover typical use cases for the library.
React Router (route loader)
By utilizing useParams
from react-router-dom
we can create a loader that will load data based on the route parameters.
import {
withLoader,
createLoader,
} from "@ryfylke-react/rtk-query-loader";
import { useParams, Redirect } from "react-router-dom";
// ...
const userRouteLoader = createLoader({
useQueries: () => {
const { userId } = useParams();
const userQuery = useGetUserQuery(userId, {
skip: userId ? false : true,
});
return {
queries: {
userQuery,
},
};
},
onLoading: (props) => {
const { userId } = useParams();
if (!userId) {
return <Redirect to="/users" />;
}
return <PageSkeleton />;
},
onError: (props, error) => <ErrorView error={error} />,
});
Reusable loader
We can also create a reusable loader that can be used with multiple components.
import {
withLoader,
createLoader,
ConsumerProps,
} from "@ryfylke-react/rtk-query-loader";
type UserLoaderProps = {
userId: string;
};
const userLoader = createLoader<UserLoaderProps>({
queriesArg: (props: UserLoaderProps) => props.userId,
useQueries: (userId) => {
const userQuery = useGetUserQuery(userId);
return {
queries: {
userQuery,
},
};
},
onLoading: (props) => <PageSkeleton />,
onError: (props, error) => <ErrorView error={error} />,
});
You can now use the userLoader
in any component whos props extend UserLoaderProps
.
Consumer 1
UserProfile.tsx
import { userLoader } from "../loaders";
type UserProfileProps = {
userId: string;
// ... other props
};
export const UserProfile = withLoader(
(props: UserProfileProps, data) => {
return <>...</>;
},
userLoader
);
Consumer 2
UserProfile.tsx
import { userLoader } from "../loaders";
type InlineUserDetailsProps = {
userId: string;
dir: "row" | "column";
// ... other props
};
export const InlineUserDetails = withLoader(
(props: InlineUserDetailsProps, data) => {
return <>...</>;
},
userLoader
);
Stateful loader
You can also create loaders that contain state.
const loader = createLoader({
useQueries: () => {
const [name, setName] = useState("charizard");
const debouncedName = useDebounce(name, 200);
const pokemon = useGetPokemon(debouncedName);
return {
queries: {
pokemon,
},
payload: {
name,
setName,
},
};
},
});
const Consumer = withLoader((props, data) => {
return (
<div>
<input
value={data.payload.name}
onChange={(e) => data.payload.setName(e.target.value)}
/>
<div>AP: {data.queries.pokemon.data.ability_power}</div>
</div>
);
}, loader);