Reputation: 754
There are many answers to this question, but they only answer about either they are missing or forgot to replace any keywords such as exact
, Redirect
etc., or the flow of code.
Recently I have upgraded my react app from react-router-dom: "^5.2.0"
to "react-router-dom": "^6.3.0"
. I have followed the Migrate to v6 from v5 guide and I am not able to see components rendering on particular routes. As part of only react-router-dom
, I am only adding routes
part of the React app
and component
. The way I followed the migration guide is as below:
index.js
const container = document.getElementById('root');
// Create a root.
const root = createRoot(container);
root.render(
<Provider store={Store}>
<BrowserRouter>
<Routes>
<Route path="/*" element={<App />} />
</Routes>
</BrowserRouter>
</Provider>
);
serviceWorker.unregister();
App.tsx
const App: FunctionComponent<IAppProps> = () => {
/* other stuff useEffect and fetch functions etc... */
return (
<ThemeProvider theme={theme}>
<ResetStyles />
<Routes>
{/* Public Facing */}
<Route path="*" element={<ViewLogin />} />
<Route path="/forgotten-password/*" element={<ViewForgottenPassword />} />
<Route path="/user/signup" element={<ViewUserSignup />} />
{/* User Protected */}
<Route path="/account-selection/" element={<ViewAccountSelection />} />
<Route path="/sign-out" element={<ViewSignOut />} />
<Route path="/user" element={<ViewUserConfiguration />} />
<Route path="/404" element={<ViewError404 />} />
<Route path="/:account/" element={<ViewDashboard />} />
{/* Error Pages */}
<Route element={<Navigate to="/404" />} />
</Routes>
</ThemeProvider>
);
};
export default App;
dashboard.tsx
const ViewDashboard = (props: any) => {
/* other stuff useEffect and fetch functions etc... */
return (
<div className="dashboard-container">
<Nav showSidebar={showSidebar} toggleSidebar={toggleSidebar} />
<div className={showSidebar ? 'dashboard-view-expanded' : 'dashboard-view-collapsed'}>
<ViewMenu sidebarExpanded={showSidebar} history={props.history} upperMenuTitle={getTitle()} />
<div className="dashboard-view__content">
<Routes>
<Route path="/:account/" element={<Navigate to={`${account.token}/reports/dashboard`} />} />
<Route path="/:account/account-management/*" element={<LayoutAccountManagement />} />
<Route path="/:account/reports/" element={<LayoutReport />} />
<Route element={<Navigate to="/404" />} />
</Routes>
</div>
<ViewModal />
<ViewNotification />
<ViewPopup />
</div>
</div>
);
};
export default memo(ViewDashboard, isEqual);
render
method of account-selection.js
render() {
if (this.props.user.isLoggedIn !== true) {
return <Navigate push to="/" />;
} else if (this.state.isLoading === true) {
return <ViewLoadingSplash />;
} else if (this.state.hasAccount || this.props.account.isSelected) {
console.log('Gone through account selection');
this.props.setDisplayMenu(true);
return <Navigate push to={`/${this.props.account.token}`} />;
}
return (
<div id="account-selection__view">
<div className="account-selection__content">
<div className="account-selection__content__selection">
<h3>Select Account</h3>
<ComponentInputField
value={this.state.search}
onChange={this.onInputChange}
placeholder="Search accounts..."
type="text"
/>
<ComponentList rows={this.state.visibleAccounts} onRowClick={this.onAccountClick} />
</div>
</div>
<ViewNotifications />
</div>
);
}
Now the app flow is, on login, there is an account selection page where I select users and it will take me to their dashboard.
If everything is working correctly we should see the following route and the user's dashboard:
http://localhost:3000/demoUser/reports/dashboard
Instead, it is taking me to http://localhost:3000/demoUser
with no dashboard view at all.
Not sure where it is going wrong or if I am missing something huge in this. A proper way of doing this would be appreciated.
Upvotes: 1
Views: 1027
Reputation: 203418
The issues I see are the Routes
components are rendering routes with paths without a trailing "*"
wildcard character to allow descendent route path matching. From what I can see you want the user to navigate to "/account-selection"
and render the ViewAccountSelection
component which under the correct conditions will navigate the user to "/demoUser"
, i.e. the "/:account"
route renders ViewDashboard
component. The ViewDashboard
then navigates the user to "/demoUser/reports/dashboard"
to render the LayoutReport
component.
Add the missing wildcard path characters to the routes that need it.
App
<Routes>
{/* Public Facing */}
<Route path="*" element={<ViewLogin />} />
<Route
path="/forgotten-password/*"
element={<ViewForgottenPassword />}
/>
<Route path="/user/signup" element={<ViewUserSignup />} />
{/* User Protected */}
<Route
path="/account-selection/"
element={
<ViewAccountSelection
account={account}
user={{ isLoggedIn: true }}
/>
}
/>
<Route path="/sign-out" element={<ViewSignOut />} />
<Route path="/user" element={<ViewUserConfiguration />} />
<Route path="/404" element={<ViewError404 />} />
<Route path="/:account/*" element={<ViewDashboard />} /> // <-- here
{/* Error Pages */}
<Route element={<Navigate to="/404" />} />
</Routes>
ViewDashboard
const ViewDashboard = () => (
<div className="dashboard-container">
...
<div className="dashboard-view__content">
<Routes>
<Route
index // <-- index route, i.e. "/:account"
element={<Navigate to="reports/dashboard" />} // <-- navigate relative
/>
<Route
path="/account-management/*"
element={<LayoutAccountManagement />}
/>
<Route path="/reports/*" element={<LayoutReport />} /> // <-- add trailing *
<Route element={<Navigate to="/404" />} />
</Routes>
</div>
...
</div>
</div>
);
Upvotes: 1