Rules Hub

Coding Rules Library

← Back to all rules
frontend ruleStack: react
react-routerloadersarchitecturedependency-injectionclean-code

Prefer React Router Context for loader dependencies

Inject dependencies into loaders using React Router's context middleware instead of closures or globals to improve testability and type safety.

PR: Feat/FCK-2245 - Cache Bellsheep and profile loaders with TanStack Query #343Created: Dec 10, 2025

Bad example

Old codets
1// Bad: Using a factory function (closure) to inject dependencies
2// This requires manual wiring in the route definition and complicates typing.
3export const makeLoader = (queryClient: QueryClient) =>
4 async ({ request }: LoaderFunctionArgs) => {
5 await queryClient.ensureQueryData({ ... });
6 return json({ ... });
7 };
8
9// Usage elsewhere requires invoking the factory:
10// loader: makeLoader(queryClient)

Explanation (EN)

Using closures or factory functions to inject dependencies like `QueryClient` creates unnecessary boilerplate and complicates route definitions. It also makes type inference for loader data more difficult.

Objašnjenje (HR)

Korištenje zatvaranja (closures) ili tvorničkih funkcija za umetanje ovisnosti poput `QueryClient` stvara nepotreban kod i komplicira definicije ruta. Također otežava zaključivanje tipova (type inference) za podatke iz loadera.

Good example

New codets
1// Good: Accessing dependencies directly via React Router Context
2import { queryClientContext } from '@/app/contexts';
3
4export const loader = async ({ context }: LoaderFunctionArgs) => {
5 // Clean, type-safe access without external wiring
6 const queryClient = context.get(queryClientContext);
7
8 await queryClient.ensureQueryData({ ... });
9 return { ... };
10};

Explanation (EN)

React Router's middleware context allows loaders to request dependencies directly. This eliminates the need for wrapper functions, keeps the API clean, and improves testability by allowing contexts to be easily mocked.

Objašnjenje (HR)

Kontekst (middleware) React Routera omogućuje loaderima izravan zahtjev za ovisnostima. To uklanja potrebu za omotačima (wrapperima), održava API čistim i poboljšava testabilnost omogućujući lako mockanje konteksta.

Notes (EN)

This pattern requires enabling `v8_middleware: true` in the React Router configuration and defining the `Future` interface in TypeScript.

Bilješke (HR)

Ovaj obrazac zahtijeva omogućavanje `v8_middleware: true` u konfiguraciji React Routera i definiranje `Future` sučelja u TypeScriptu.