Skip to content
IC Reactor

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"
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:

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} />
}