Reputation: 610
Basically I am understanding someone else's code and modifying. In App.js it is checked if the user is logged in, he has to render the dashboard
App.js
<Switch>
<Redirect exact path="/" to="/dashboard"/>
<Route path="/login" component={GuestBoard} />
<EnsureSignedIn>
<Switch>
<Route path="/dashboard/" component={Dashboard}/>
<Route path="/welcome/" component={Welcome}/>
</Switch>
</EnsureSignedIn>
</Switch>
Basically <EnsureSignedIn>
checks if the user has logged in, it renders all the children.
My question is: how <Switch>
is rendering <EnsureSignedIn>
which has no path. And also what exactly happens(what is the flow of rendering of components) if I keep writing React Components inside <Switch>
?
Say something like this
<Switch>
<Redirect exact path="/" to="/dashboard"/>
<Route path="/login" component={GuestBoard} />
<Component1 />
<Component2 />
<Component3 />
</Switch>
EnsureSignedIn:
componentDidMount() {
if (!this.props.user) {
this.props.history.push('/login?next=' + this.props.currentURL);
}
render() {
return (this.props.user ? this.props.children : null);
}
We have used redux, So user is props from the reducer.
Upvotes: 0
Views: 106
Reputation: 17271
Switch is working as intended here even though the documentation recommended only having a Route
or Redirect
component as a direct child. It is however documented that Switch will render a single child - the first child which matches the current route. It also specifies that a <Route
component without a path is allowed as a catch-all, that is what is happening here.
To simplify, Switch will iterate over all of its children, one by one, from top down, and select the first component where the path matches the current route or the component has no path specified (catch-all component). You can see this working here: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/Switch.js#L47 note that it's looking for the props of a Route
component but there is no code specifically requiring the component to be a Route
.
In your case, unauthenticated pages will render just fine, because they appear before the EnsureSignIn
child component. However, if no other routes match, EnsureSignIn
will be rendered and, presumably, this component will redirect back to the login page if the user is not signed in - preventing them from accessing the protected pages beneath.
If you were to restructure your code like this:
<Switch>
<span>Hello!!</span>
<Redirect exact path="/" to="/dashboard"/>
<Route path="/login" component={GuestBoard} />
<EnsureSignedIn>
<Switch>
<Route path="/dashboard/" component={Dashboard}/>
<Route path="/welcome/" component={Welcome}/>
</Switch>
</EnsureSignedIn>
</Switch>
That would also be completely valid, but the only thing that would ever be rendered is "Hello!!" because that's the first matching component.
Upvotes: 2