Rules Hub
Coding Rules Library
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.
Bad example
| 1 | // Bad: Using a factory function (closure) to inject dependencies |
| 2 | // This requires manual wiring in the route definition and complicates typing. |
| 3 | export 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
| 1 | // Good: Accessing dependencies directly via React Router Context |
| 2 | import { queryClientContext } from '@/app/contexts'; |
| 3 |
|
| 4 | export 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.