Skip to content

Factory Functions Overview

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"
FactorySuspenseDynamic ArgsUse Case
createQueryVia Factory variantStandard queries with enabled
createSuspenseQueryVia Factory variantSuspense-based loading
createMutationN/AArgs at call timeState mutations
createInfiniteQueryVia Factory variantPagination/infinite scroll
createSuspenseInfiniteQueryVia Factory variantSuspense pagination

Organize all your queries in a dedicated file:

src/queries/index.ts
import { createQueryFactory, createMutation } from "@ic-reactor/react"
import { backend } from "../reactor"
// Query factories
export const getUserQuery = createQueryFactory(backend, {
functionName: "getUser",
staleTime: 5 * 60 * 1000,
})
export const getPostsQuery = createQueryFactory(backend, {
functionName: "getPosts",
})
// Mutation factories
export const createPostMutation = createMutation(backend, {
functionName: "createPost",
invalidateQueries: [backend.generateQueryKey({ functionName: "getPosts" })],
})
// Query key helpers
export 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} />
}