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"))
}
];
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>
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
Remove the
Home
component andOutlet
fromHome
and just render the two nested routes. If the intent is to render aHome
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>Flatten all the routes and remove the
Outlet
fromHome
, 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' />} />Define a single route and use the
path
to your advantage. In other words, declare a path where thetype
is a route path param, and check thetype
from the params in theHome
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:
Tabs
inComponentC
are not working correctly as React-RouterLink
. It can be fixed usinghistory.push
in Tab'sonChange
handler.- You have not defined Routes in your nested component properly. You are using
find
to define theRoute
, that looks dirty. It can be fixed using aSwitch
andRoute
in nested component i.e.ComponentC
- You used
Route
andRedirect
to make default paths. That can be simplified as well. - You used
props.match.url
andprops.match.path
incorrectly.props.match.url
(URL) should be used inLink
orhistory.push
andprops.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
How to Condense Summable Metrics to a Unique Identifier in a Ruby Table
How to Return a Group of Sequential Numbers That Might Exist in an Array
Assets Precompiling Error with Jquery UI Plugin
Tilt (Kramdown) Preventing Erb Processing When Rendering Markdown
Sum of All Amount If Charge Dates Are the Same in Stripe
Need Help on Join Table, Limiting Results to Only the Resource Id
How to Remove Devise Password Resetting During Email Confirmation
Rails: Upload a File or Store a Url
Programming a Simple Irc (Internet-Relay-Chat) Client
Instagram Ruby Gem - Unable to Reach Callback Url
What Is the Fully Qualified Name of a Model in Ruby on Rails
Can't Run a Ruby Hello World Application in Aptana
How to Strip Commas from Float Input
Mongomapper Association Skips Duplicates