T
TanStack2w ago
sensitive-blue

What is the cleanest way to pass route parameters to component files?

I couldn't find a clear-cut example within the documentation on how you handle it when your components live in components files and your routes live under the routes path. I want to use things like use params but I don't know how to get to them without using it directly within the route file. I've thought of two ways to do it and I'm not sure which one's better. Let me know which one is the preferred pattern if there is one. Pattern 1 Determine params in the Route file and pass as props to component.
export const Route = createFileRoute("/projects_/$projectId")({
component: RouteComponent,
});

function RouteComponent() {
const { projectId } = Route.useParams();
const { tab } = Route.useSearch();

return (
<Project
projectId={projectId}
activeTab={tab}
/>
);
}
export const Route = createFileRoute("/projects_/$projectId")({
component: RouteComponent,
});

function RouteComponent() {
const { projectId } = Route.useParams();
const { tab } = Route.useSearch();

return (
<Project
projectId={projectId}
activeTab={tab}
/>
);
}
Pattern 2 Use the from parameter in global useParams within component file:
//src/routes/projects_/$projectId.jsx
export const Route = createFileRoute("/projects_/$projectId")({
component: RouteComponent,
});

function RouteComponent() {
return (
<Project />
);
}
//src/routes/projects_/$projectId.jsx
export const Route = createFileRoute("/projects_/$projectId")({
component: RouteComponent,
});

function RouteComponent() {
return (
<Project />
);
}
//src/components/Project.jsx
import { useSearch, useParams } from "@tanstack/react-router";

function Project() {
const {projectId} = useParams({from: "/projects_/$projectId"})
...
}
//src/components/Project.jsx
import { useSearch, useParams } from "@tanstack/react-router";

function Project() {
const {projectId} = useParams({from: "/projects_/$projectId"})
...
}
Pattern 3 Use the getRouteApi function.
//src/routes/projects_/$projectId.jsx
export const Route = createFileRoute("/projects_/$projectId")({
component: RouteComponent,
});

function RouteComponent() {
return (
<Project />
);
}
//src/routes/projects_/$projectId.jsx
export const Route = createFileRoute("/projects_/$projectId")({
component: RouteComponent,
});

function RouteComponent() {
return (
<Project />
);
}
//src/components/Project.jsx
import { getRouteApi } from '@tanstack/react-router'

const route = getRouteApi("/projects_/$projectId")

function Project() {
const {projectId} = route.useParams()

return <div>...</div>
}
//src/components/Project.jsx
import { getRouteApi } from '@tanstack/react-router'

const route = getRouteApi("/projects_/$projectId")

function Project() {
const {projectId} = route.useParams()

return <div>...</div>
}
9 Replies
rising-crimson
rising-crimson2w ago
If it was me, I prefer Pattern 1 for its composability, just in case it is gonna be used in another route. But the simple answer is: It depends on your project and your preferences. Neither correct nor wrong. That is just the way react is, you have free reign of what to do
sensitive-blue
sensitive-blueOP2w ago
The only one I see explicitly called out in documentation is pattern 3, so I may just follow that one!
vicious-gold
vicious-gold2w ago
I was wondering the same. With pattern 3 you are basically binding the component to the routeid. So the component will only every work on that route. But that might also be a good thing? Dont know
grumpy-cyan
grumpy-cyan2w ago
I use pattern 3 only for components explicitly linked to a route, but for leave components, I pass the props in (pattern 1) The only exception for me is using the __root route for getting app-wide context.
evident-indigo
evident-indigo2w ago
Hello, I had one question related to this. Is importing the Route instance and using it directly instead of getRouteApi an anti-pattern?
foreign-sapphire
foreign-sapphire2w ago
yes. you should not import the Route instance
evident-indigo
evident-indigo2w ago
Is it because it can mess up code splitting if it's enabled? Or is there any other bigger reasons. Would really help if you could point me to the docs where this is discussed. Thanks.
foreign-sapphire
foreign-sapphire2w ago
you can run into circularity issues, both types and runtime
evident-indigo
evident-indigo2w ago
Oh, that makes sense. On checking our repo, I see that we have this circular dependency in multiple places. I wonder why it has not caused runtime or types errors until now. I found a GitHub thread related to this (you have also commented here) - https://github.com/TanStack/router/issues/2755. Seems like we could have caught this earlier if we had the eslint-rule circular dependency. Thank you for you help.

Did you find this page helpful?