Route Loaders
Prefetch data before components mount using TanStack Router or React Router loaders
Factory functions let you create reusable, pre-configured query and mutation objects. Unlike hooks which are created fresh on each render, factories create stable objects you can use across loaders, components, and utilities.
Route Loaders
Prefetch data before components mount using TanStack Router or React Router loaders
Centralized Config
Define select, staleTime, invalidateQueries once — use everywhere
Cache Access
Read/invalidate cache outside of React components
Type Safety
Get consistent types across your entire app
import { // Query factories createQuery, createQueryFactory, createSuspenseQuery, createSuspenseQueryFactory,
// Mutation factory createMutation,
// Infinite query factories createInfiniteQuery, createInfiniteQueryFactory, createSuspenseInfiniteQuery, createSuspenseInfiniteQueryFactory,} from "@ic-reactor/react"| Factory | Suspense | Dynamic Args | Use Case |
|---|---|---|---|
createQuery | ❌ | Via Factory variant | Standard queries with enabled |
createSuspenseQuery | ✅ | Via Factory variant | Suspense-based loading |
createMutation | N/A | Args at call time | State mutations |
createInfiniteQuery | ❌ | Via Factory variant | Pagination/infinite scroll |
createSuspenseInfiniteQuery | ✅ | Via Factory variant | Suspense pagination |
Organize all your queries in a dedicated file:
import { createQueryFactory, createMutation } from "@ic-reactor/react"import { backend } from "../reactor"
// Query factoriesexport const getUserQuery = createQueryFactory(backend, { functionName: "getUser", staleTime: 5 * 60 * 1000,})
export const getPostsQuery = createQueryFactory(backend, { functionName: "getPosts",})
// Mutation factoriesexport const createPostMutation = createMutation(backend, { functionName: "createPost", invalidateQueries: [backend.generateQueryKey({ functionName: "getPosts" })],})
// Query key helpersexport const queryKeys = { users: () => backend.generateQueryKey({ functionName: "getUser" }), userById: (id: string) => backend.generateQueryKey({ functionName: "getUser", args: [id], }), posts: () => backend.generateQueryKey({ functionName: "getPosts" }),}import { createFileRoute } from "@tanstack/react-router"import { getUserQuery } from "../queries"
export const Route = createFileRoute("/users/$userId")({ // Prefetch in loader loader: async ({ params }) => { return { user: await getUserQuery(params.userId).fetch() } },
component: UserPage,})
function UserPage() { // Data already loaded, instant render const { data } = getUserQuery(Route.useParams().userId).useQuery() return <Profile user={data} />}import { json, useLoaderData } from "react-router-dom"import { getUserQuery } from "../queries"
export async function loader({ params }) { const user = await getUserQuery(params.userId).fetch() return json({ user })}
export function UserPage() { const { user } = useLoaderData() return <Profile user={user} />}