How to Link to a Nested Route Path Inside a Loop

how to link to a nested route path inside a loop?

<% story.substories.each do |substory| %>
<%= substory.title %>
<%= substory.subplot %>

<% if substory %>
<%= link_to 'Edit', edit_story_substory_path(substory.story, substory) %>
<% end %>

<% end %>

You just made a typo. @substory would work too if you declare it on your Stories#index

react router - properly using links inside nested routes


Your code is working fine, but you have to add some additional logic to pass down the right props when /articles/:postSlug match.

Example

class Blog extends React.Component {
render() {
const posts = [
{ id: 1, title: "Post 1", slug: "post-1" },
{ id: 2, title: "Post 2", slug: "post-2" },
{ id: 3, title: "Post 3", slug: "post-3" }
];

return (
<>
<Header />
<Switch>
<Route
exact
path="/"
render={() => (
<Feed posts={posts} />
)}
/>
<Route
path="/articles/:postSlug"
render={props => {
const post = posts.find(p => p.slug === props.match.params.postSlug);

if (!post) {
return null;
}
return <Post {...props} postTitle={post.title} postSlug={post.slug} />;
}}
/>
</Switch>
</>
);
}
}

I need a nested route in react router V5

Within the Switch component path order and specificity matters! You want to order the routes from more specific paths to less specific paths. In this case you are rendering the "/access" path prior to any of the sub-route "/access/***" paths, so it is matched and rendered instead of the one really matching the path in the URL.

To fix, move the "/access" route config below the more specific routes.

export const ROUTES = [
// move "/access" route from here
{
name: "addTeam",
path: "/access/add-team",
component: lazy(() => import("./AddTeam"))
},
{
name: "addUser",
path: "/access/add-user",
component: lazy(() => import("./AddUser"))
},
// to here
{
name: "access",
path: "/access",
component: lazy(() => import("./Access"))
},
{
name: "admin",
path: "/admin",
component: lazy(() => import("./Admin"))
}
];

Sample Image

React nested routes for every folder

How can I segregate these nested routes
("/wordmaster/anything_here/anything_here_again") into their component
folders?

You can move these routes into the component you want to render them. They would be rendered again into a Routes component.

Example:

App - renders the base/root routes, wildcard * appended to route paths so sub-routes can be matched.

<Routes>
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard/*" element={<Dashboard />} />
<Route path="/wordy/*" element={<Wordy />} />
<Route path="/cetrec/*" element={<Cetrec />} />
</Routes>

Wordy - Renders relative links and paths.

<ul>
<li>
<Link to="learn">Learn</Link>
</li>
<li>
<Link to="learn/rumbo">Rumbo</Link>
</li>
<li>
<Link to="rev">Rev</Link>
</li>
</ul>
<Routes>
<Route path="learn" element={<LearnWindow />} />
<Route path="learn/rumbo" element={<SomeOtherComponent />} />
<Route path="rev" element={<RevWindow />} />
</Routes>

Edit react-nested-routes-for-every-folder

You can keep breaking the routes down as granularly as you need.

Also, what exactly does this Routes tag do, does it play any role in
rendering of the component?

It does play a role in the rendering of the component. It's the component that takes the children routes, computes the best match, and renders it.

Routes source

/**
* A container for a nested tree of <Route> elements that renders the branch
* that best matches the current location.
*
* @see https://reactrouter.com/docs/en/v6/api#routes
*/
export function Routes({
children,
location
}: RoutesProps): React.ReactElement | null {
return useRoutes(createRoutesFromChildren(children), location);
}

Can I use it anywhere in the return code and can I use it(call a Link
to path) before these Routes are defined?

Use the Routes component anywhere you are rendering a Route component. The only valid children of Routes is Route and React.Fragment, and all Route components can only be a child of the Routes component or another Route (in the case of nesting routes). Links and routes can be declared independently of each other, but it doesn't make much sense to link to routes that don't exist.

React Router Dom V6 Nested Route Attributes

From what I can tell the RRDv6 code isn't an accurate conversion. The v6 version is recursively rendering the Home component. The nested routes shouldn't also be using absolute paths.

Suggestions

  1. Remove the Home component and Outlet from Home and just render the two nested routes. If the intent is to render a Home component without any type then use an index route.

    const Home = ({ type }) => {
    return (
    <div className='home'>
    <Navbar />
    <Featured type={type} />
    <List />
    <List />
    <List />
    <List />
    </div>
    );
    };

    ...

    <Route path="/">
    <Route index element={<Home />} />
    <Route path="movies" element={<Home type='movies' />} />
    <Route path="series" element={<Home type='series' />} />
    </Route>
  2. Flatten all the routes and remove the Outlet from Home, which is basically the same as above but now uses absolute paths.

    const Home = ({ type }) => {
    return (
    <div className='home'>
    <Navbar />
    <Featured type={type} />
    <List />
    <List />
    <List />
    <List />
    </div>
    );
    };

    ...

    <Route path="/" element={<Home />} />
    <Route path="/movies" element={<Home type='movies' />} />
    <Route path="/series" element={<Home type='series' />} />
  3. Define a single route and use the path to your advantage. In other words, declare a path where the type is a route path param, and check the type from the params in the Home component.

    const Home = () => {
    const { type } = useParams();
    return (
    <div className='home'>
    <Navbar />
    <Featured type={type} />
    <List />
    <List />
    <List />
    <List />
    </div>
    );
    };

    ...

    <Route path="/" element={<Home />} />
    <Route path="/:type" element={<Home />} />

Nested routes inside a route not working - React

Issues:

  1. Tabs in ComponentC are not working correctly as React-Router Link. It can be fixed using history.push in Tab's onChange handler.
  2. You have not defined Routes in your nested component properly. You are using find to define the Route, that looks dirty. It can be fixed using a Switch and Route in nested component i.e. ComponentC
  3. You used Route and Redirect to make default paths. That can be simplified as well.
  4. You used props.match.url and props.match.path incorrectly. props.match.url (URL) should be used in Link or history.push and props.match.path (PATH) should be used in path of your nested Routes declarations.

Solution:

After fixing all the issues mentioned above, Here is the working code:

(Also, note that the Route that has nested routes should not be marked exact={true})

Main Routes:

const routes = [
{ exact: true, label: "Component A", path: "/routeA", component: ComponentA },
{ exact: true, label: "Component B", path: "/routeB", component: ComponentB }
{ exact: false, label: "Component C", path: "/routeC", component: ComponentC }
// ^ it is false because it has nested routes
];

// JSX
<BrowserRouter>

{routes.map((item) => (
<Link key={item.path} to={item.path}>
{item.label}
</Link>
))}

<Switch>
{routes.map((route) => {
return (
<Route
key={route.path}
exact={route.exact}
path={route.path}
component={route.component}
/>
);
})}
<Redirect exact from="/" to="/routeA" />
</Switch>
</BrowserRouter>

And Here is nested routes declarations inside ComponentC:

const routes = [
{
label: "Component C1",
code: "subC1",
component: ComponentC1
},
{
label: "Component C2",
code: "subC2",
component: ComponentC2
},
{
label: "Component C3",
code: "subC3",
component: ComponentC3
}
];

export default function ComponentC(props) {
const [tabId, setTabId] = useState(routes[0].code);
const handleTabChange = (tabId) => {
props.history.push(`${props.match.url}/${tabId}`);
setTabId(tabId);
};

return (
<>
<Tabs onChange={handleTabChange} selectedTabId={tabId}>
{routes.map((tab) => {
return <Tab key={tab.code} id={tab.code} title={tab.label} />;
})}
</Tabs>

<Switch>
{routes.map((route) => (
<Route
key={route.code}
exact
path={`${props.match.path}/${route.code}`}
component={route.component}
/>
))}
<Redirect
exact
from={props.match.url}
to={`${props.match.url}/${routes[0].code}`}
/>
</Switch>
</>
);
}

Here is full demo on Sandbox.

React nested Routing react-route-dom v6

You are overcomplicating things since react-router-dom@6 can handle relative links automatically. In other words, there's no need to try and build your own relative links and paths from a "current path" manually. From what I can see you need the links to link to sibling routes of the current location/path.

Use a relative path prefixed with ".." to navigate relative to the parent path, i.e. to="../components".

Example:

<Link className="maintenance-nav-list-card" to="../components">
<img className="maintenance-nav-list-image" src={components} />
<span>Components</span>
</Link>

If VesselMaintenance is rendered on "/maintenance/XXXX" then linking to "../components", "../worklist", "../runninghours", etc... will navigate between these sibling routes/paths.



Related Topics



Leave a reply



Submit