T
TanStackโ€ข2y ago
correct-apricot

Is it a good idea to pass the route to a Component?

Hey ๐Ÿ‘‹๐Ÿฝ , I want to have access to the route.fullPath or the route.id and the numerous hooks at a child component. Here's my code:
import { createFileRoute } from "@tanstack/react-router";

import { CreateForm } from "@/features/create-vouchers";
import { Loading } from "shared-ui/loading";
import { Alert } from "shared-ui/alert";

export const Route = createFileRoute("/app/vouchers/creation/create")({
pendingComponent: () => <Loading size="md" />,
errorComponent: ({ error }) => (
<Alert type="error">{error.errorMessage}</Alert>
),
component: CreateComponent,
});

function CreateComponent() {
return <CreateForm route={Route} />;
}
import { createFileRoute } from "@tanstack/react-router";

import { CreateForm } from "@/features/create-vouchers";
import { Loading } from "shared-ui/loading";
import { Alert } from "shared-ui/alert";

export const Route = createFileRoute("/app/vouchers/creation/create")({
pendingComponent: () => <Loading size="md" />,
errorComponent: ({ error }) => (
<Alert type="error">{error.errorMessage}</Alert>
),
component: CreateComponent,
});

function CreateComponent() {
return <CreateForm route={Route} />;
}
Can you tell me whether this is a good idea or how you solve it? I want to navigate in the child component and I need the route.id for this. Thanks
12 Replies
wise-white
wise-whiteโ€ข2y ago
There's a possibility of this creating a circular dependency with your types. If you need the routeId it can get gotten using the getRouteApi helper.
import { getRouteApi } from '@tanstack/react-router';

const routeApi = getRouteApi('/posts/$postId')

const Component = () => {
const routeId = routeApi.id;
const search = routeApi.useSearch();
...
}
import { getRouteApi } from '@tanstack/react-router';

const routeApi = getRouteApi('/posts/$postId')

const Component = () => {
const routeId = routeApi.id;
const search = routeApi.useSearch();
...
}
The route's full-path needs to be defined since that is specific to each navigation.
correct-apricot
correct-apricotOPโ€ข2y ago
Thanks @Sean Cassiere, I'm on plain JavaScript. OK, what do you think about the following code?
import {
createFileRoute,
useNavigate,
getRouteApi,
} from "@tanstack/react-router";

import { CreateForm } from "@/features/create-vouchers";
import { Loading } from "shared-ui/loading";
import { Alert } from "shared-ui/alert";

export const Route = createFileRoute("/app/vouchers/creation/create")({
pendingComponent: () => <Loading size="md" />,
errorComponent: ({ error }) => (
<Alert type="error">{error.errorMessage}</Alert>
),
component: CreateComponent,
});

const routeApi = getRouteApi(Route.id);

function CreateComponent() {
const navigate = useNavigate({ from: routeApi.id });
const goToNextStep = () => navigate({ to: "/app/vouchers/creation/output" });
return <CreateForm onNextStep={goToNextStep} />;
}
import {
createFileRoute,
useNavigate,
getRouteApi,
} from "@tanstack/react-router";

import { CreateForm } from "@/features/create-vouchers";
import { Loading } from "shared-ui/loading";
import { Alert } from "shared-ui/alert";

export const Route = createFileRoute("/app/vouchers/creation/create")({
pendingComponent: () => <Loading size="md" />,
errorComponent: ({ error }) => (
<Alert type="error">{error.errorMessage}</Alert>
),
component: CreateComponent,
});

const routeApi = getRouteApi(Route.id);

function CreateComponent() {
const navigate = useNavigate({ from: routeApi.id });
const goToNextStep = () => navigate({ to: "/app/vouchers/creation/output" });
return <CreateForm onNextStep={goToNextStep} />;
}
Here I keep the router logic away from the child component.
wise-white
wise-whiteโ€ข2y ago
Yea that'd work.
correct-apricot
correct-apricotOPโ€ข2y ago
Thanks
absent-sapphire
absent-sapphireโ€ข2y ago
Out of Curiosity: why wouldn't you use Route.useNavigate inside CreateComponent? (assuming your whole code snippet is from one file)
wise-white
wise-whiteโ€ข2y ago
The Route object doeesn't have a typed useNavigate hook attached to it. It only has useLoaderData, useLoaderDeps, useMatch, useParams, useSearch, and useRouteContext
dependent-tan
dependent-tanโ€ข2y ago
we could add this, if it helps?
absent-sapphire
absent-sapphireโ€ข2y ago
Thanks for your response. I wrongly assumed that useNavigate is part of the Route object. Don't know if it's need on Route but would make its API maybe more consistent?
dependent-tan
dependent-tanโ€ข2y ago
PRs are always welcome if you want to do it
optimistic-gold
optimistic-goldโ€ข2y ago
that sounds like a good idea it's actually pretty easy. I'll try to PR it
absent-sapphire
absent-sapphireโ€ข2y ago
That was fast! ๐Ÿ˜ณ

Did you find this page helpful?