Reputation: 720
TLDR: I'm trying to figure out how to arrange nested routes and my components so that a component can be swapped out based on route.
In SUPER simple terms, I'm trying to build an application where teachers can see the classes they teach at colleges.
The routes of the application are:
/dashboard
: call backend to check if the teacher has a default college set on their account, if not then present a college picker dialog where the teacher can select a default college. Once there's a default college (say COLLEGE1
), re-route to next route (next bullet point)/dashboard/college/COLLEGE1
: fetch metadata of classes taught in college./dashboard/college/COLLEGE1/class/CLASS1
: show metadata of a single class within COLLEGE1
. This route is accessed by clicking a class in bullet 2.Here are rough mocks of what this interaction would look like when static (I've colored each component so it's easier for you to refer to them when responding):
However, I am just not able to figure out the nested routes + component hierarchy structure that would get me this.
The hierarchy I have so far is:
<Home>
<Header/>
<!-- content in header -->
</Header>
<MainContent>
<!-- Either loading, for e.g. to fetch permissions -->
<Loading />
<!-- OR display navigation + content -->
<MainContentPage>
<!-- show navigation pane on left, and then choose from report / T and Cs / Contact -->
<Navigation>
<CurrentCollegeInfo />
<DashboardLink />
<TermsAndConditionsLink />
<ContactUsLink />
</Navigation>
<ReportPage>
<!-- Either Loading -->
<Loading />
<!-- OR have user select default college -->
<DefaultCollegePickerPopup />
<!-- OR show college report or class details -->
<CollegeReportPage />
<ClassDetailsPage />
<!-- OR error pages: Not Found, 500, etc. -->
<ErrorPage />
</ReportPage>
<TermsAndConditionsPage />
<ContactUsPage />
</MainContentPage>
</MainContent>
</Home>
How do I insert route management here (I'm using react-router library at the moment btw) so that in the ReportPage component:
/dashboard
(when loading default college from backend or asking user to pick one)/dashboard/college/COLLEGE1
and fetch college report/dashboard/college/COLLEGE1/class/CLASS1
and fetch class details?Or is this not possible and I should rather figure out another flow?
Upvotes: 0
Views: 170
Reputation: 195
So if I understand correctly, you want to use the react-router
to load different components based on which endpoint the user is on? This is 100% possible. You just pass the component you want to show for a specific route as a component property.
You can also use parameters in the paths, so in your example, you have /dashboard/COLLEGE1
... I'm assuming you need that to be dynamic to allow for any college. This is done with placing parameters into the path like so... /dashboard/:somevariablename
.
<Route
// exact
path={"/dashboard"}
// path={"/dashboard/:collegeId"}
// path={"/dashboard/:collegeId/classes/:classId"}
component={ComponentToPass}
/>
If you make a Route
for every possible component/page that the user can visit, and wrap it in a <Switch>
component, it will show only one component. You can however skip the <Switch>
and add multiple routes to an endpoint as well.
I'm assuming you'll need to use the collegeId and classId in the corresponding components. If you are using functional react, use const { VARNAME } = useParams()
to retrieve the parameters you are using. If you are using class-based react, all you need to do is call this.props.match.VARNAME
. -- Both are obviously used inside the component that you want to show/use.
So to change your code up a little bit (could be done in a dedicated routes component), heres a light example..
import {HashRouter, Switch, Route} from "react-router-dom"
import DefaultCollegePickerPopup from './wherever'
import CollegeReportPage from './wherever'
import ClassDetailsPage from './wherever'
function RouterComponent(props) {
return (
<HashRouter>
<Switch>
<Route
exact
path={"/dashboard"}
component={DefaultCollegePickerPopup}
/>
<Route
exact
path={"/dashboard/:collegeId"}
component={CollegeReportPage}
/>
<Route
exact
path={"/dashboard/:collegeId/class/:classId"}
component={ClassDetailsPage}
/>
</Switch>
</HashRouter>
)
}
function CollegeReportPage(props) {
const { collegeId } = useParams();
return (
<div>College report for {collegeId}</div>
)
}
class CollegeReportPage extends React.Component {
render() {
const { collegeId } = this.props.match
return (
<div>College report for {collegeId}</div>
)
}
}
If you haven't already looked at this, I would. It gives a LOT of useful information.
https://reactrouter.com/web/guides/quick-start
Upvotes: 1