I am trying to create some nested routes in a react project using the useRoutes
hook. But I am struggling to make the URL
show as I want.
The example struture project is this one:
- public
- src
- Components
- Header.js
- MaterialsDetails.js
- Materials.js
- TitleDetails.js
- Titles.js
- App.js
- index.js
- routes.js
I have create the routes in routes.js
like this:
import { Outlet } from "react-router-dom";
import Titles from "./Components/Titles";
import TitleDetails from "./Components/TitleDetails";
import Materials from "./Components/Materials";
import MaterialDetails from "./Components/MaterialDetails";
import Header from "./Components/Header";
const routes = [
{
path: "/",
element: <Header />,
children: [
{
path: "/titles",
element: <Outlet />,
children: [
{
index: true,
element: <Titles />
},
{ path: ":id", element: <TitleDetails /> }
]
},
{
path: "/materials",
element: <Outlet />,
children: [
{
index: true,
element: <Materials />
},
{ path: ":id", element: <MaterialDetails /> }
]
}
]
}
];
export default routes;
Then I have the HeaderLayout.js
that will be shown in every page:
import React from "react";
import { Outlet } from "react-router-dom";
export default function HeaderLayout() {
return (
<>
<h1>Header Layout</h1>
<Outlet />
</>
);
}
In titles.js
I have a list of titles where each title has its details when clicking on it:
import React from "react";
import { Link } from "react-router-dom";
export default function Titles() {
return (
<>
<h3>Titles</h3>
<p>
<Link to="1">Title example 1</Link>
</p>
<p>
<Link to="2">Title example 2</Link>
</p>
<p>
<Link to="3">Title example 3</Link>
</p>
</>
);
}
Then in TitleDetails.js
apart of having the title detail I have a link to go to the related materials. So when I click I will go to the list of materials:
import React from "react";
import { useParams } from "react-router-dom";
import { Link } from "react-router-dom";
export default function TitleDetails() {
const { id } = useParams();
return (
<>
<h1>Details of title {id}</h1>
Related materials: <Link to="/materials">Materials</Link>
</>
);
}
And finally in Materials.js
I have the same concept as Titles.js
. A list of materials that when I click on one I will go to MaterialDetails.js
import React from "react";
import { Link } from "react-router-dom";
export default function Materials() {
return (
<>
<h3>Materials</h3>
<p>
<Link to="1">Material example 1</Link>
</p>
<p>
<Link to="2">Material example 2</Link>
</p>
<p>
<Link to="3">Material example 3</Link>
</p>
</>
);
}
The question is how can I modify routes.js
to obtain, for example, that URL: http://localhost:3000/titles/1/materials/3
instead of going to http://localhost:3000/materials
when I amb in http://localhost:3000/titles/1
?
Thank you!
I found the solution to my problem:
I changed routes.js
to:
import { Outlet } from "react-router-dom";
import Titles from "./Components/Titles";
import TitleDetails from "./Components/TitleDetails";
import Materials from "./Components/Materials";
import MaterialDetails from "./Components/MaterialDetails";
import HeaderLayout from "./Components/HeaderLayout";
const routes = [
{
path: "/",
element: <HeaderLayout />,
children: [
{
path: "/titles",
element: <Outlet />,
children: [
{
index: true,
element: <Titles />
},
{ path: ":id", element: <TitleDetails /> },
{ path: ":id/materials", element: <Materials /> },
{ path: ":id/materials/:idMaterial", element: <MaterialDetails /> }
]
}
]
}
];
export default routes;
and then in TitleDetails.js I removed the /
of /materials
:
import React from "react";
import { useParams } from "react-router-dom";
import { Link } from "react-router-dom";
export default function TitleDetails() {
const { id } = useParams();
return (
<>
<h1>Details of title {id}</h1>
Related materials: <Link to="materials">Materials</Link>
</>
);
}