Reputation: 1721
I'm building an app with React and I'm using React routes.
I have 3 main routes:
index.js
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<div>
<Switch>
<Route path="/" component={App} />
<Route path="/login" component={Login} />
<Route path="/forgotPassword" component={ForgotPassword} />
</Switch>
</div>
</Suspense>
</BrowserRouter>
</Provider>,
document.getElementById('root')
);
App.js
{this.props.location.pathname === "/" && <Dashboard />}
<Route exact path="/users" component={Users} />
<Route path="/users/:id" component={UserPage} />
{!authenticated && <Redirect to="/login" />}
When I try to open "/"
, it redirects to "/login"
but it doesn't render Login
component.
When I replace {!authenticated && <Redirect to="/login" />}
with {!authenticated && <Login>}
it renders the component properly, but it doesn't change the url and it won't show the ForgotPassword page.
How do I set this properly?
Upvotes: 3
Views: 125
Reputation: 29344
Problem is order of the Route
components and the use of Switch
component.
When you redirect to /login
, Switch
will render the first matching route; for the /login
route, /
route also matches.
This is why Login
component isn't rendered. App
component is rendered for both /
and /login
routes.
Couple of solutions to this problem are described below:
exact
prop
One way to solve the problem is to use the exact prop. This will ensure that /
route doesn't matches /login
BUT it will cause another problem: nested routes inside App
component won't be rendered. This is because for nested route to be rendered, parent route also needs to be rendered.
Re-order the Route
components
Another solution is to change the order of your routes as:
<Switch>
<Route path="/login" component={Login} />
<Route path="/forgotPassword" component={ForgotPassword} />
<Route path="/" component={App} />
</Switch>
Upvotes: 1
Reputation: 1
You have to use render prop instead of component and the render prop give you the ability to do some checks and return the appropriate component
<Route render={(props) => !isAuth ? <Redirect to='/signin' /> : <Component {...props} /> } />
Upvotes: 0
Reputation: 169388
You'll need to reorder your switch:
<Switch>
<Route path="/login" component={Login} />
<Route path="/forgotPassword" component={ForgotPassword} />
<Route path="/" component={App} />
</Switch>
Then, maybe make that App
something like
{!authenticated ? <Redirect to="/login" /> : (
<Switch>
<Route path="/users/:id" component={UserPage} />
<Route exact path="/users" component={Users} />
<Route path="/" component={Dashboard />
</Switch>
)}
(though it could be simpler to just keep all routes in the top-level router/switch)
Upvotes: 1