Reputation: 7719
I'm using React v4.2 for my app, and it seems not to be matching the correct path for the routes:
<Provider store={store}>
<BrowserRouter>
<div>
<Switch>
<Route path="/login" render={(props) => {
if (isAuthenticated()) {
return <Redirect to='/' />;
} else {
return <LoginForm {...props}/>
}
}
} />
<EnsureLoggedInContainer>
<Route exact path="/group" render={(props) => {
debugger;
return <GroupList {...props}/>
}
}/>
<Route exact path="/group/new" render={(props) => {
debugger;
return <GroupList {...props} modal={rr}/>;
}
} />
</EnsureLoggedInContainer>
</Switch>
</div>
</BrowserRouter>
</Provider>
I have some links in the app, on which I click and I redirect the client to new URL:
_onSubmit(values) {
const { history } = this.props;
this.props.createGroup(values, ({status}) => history.push('/group'));
}
I inspect the values of props.history.location.pathname
and props.match.path
and they don't match. Why is this happening? Why is the correct route not matched?
Update 1
The code for EnsureLoggedInContainer
:
class EnsureLoggedInContainer extends Component {
componentDidMount() {
if (!isAuthenticated()) {
dispatch(setRedirectUrl(currentURL))
this.props.history.replace("/login")
}
}
render() {
if (isAuthenticated()) {
return(
<div>
<AppNavBar />
<ComponentsNavBar />
{this.props.children}
</div>
);
} else {
return <noscript />;
}
}
}
export default EnsureLoggedInContainer;
Update 2
I changed the router configuration code to the following:
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<div>
<Switch>
<Route exact path="/login" render={(props) => {
if (isAuthenticated()) {
return <Redirect to='/' />;
} else {
return <LoginForm {...props}/>
}
}
} />
<Route exact path="/register" render={(props) => {
if (isAuthenticated()) {
return <Redirect to='/' />;
} else {
return <RegisterForm {...props}/>
}
}
} />
<EnsureLoggedInContainer>
<Route exact path="/group" component={GroupList} modal={newGroupModal}/>
<Route exact path="/group/new" component={GroupList}/>
<Route component={Home} />
</EnsureLoggedInContainer>
</Switch>
</div>
</BrowserRouter>
</Provider>
, document.querySelector('.container'));
And changed the last line of EnsureLoggedInContainer
to :
export default withRouter(EnsureLoggedInContainer);
But still, I get Home
always being rendered, and random URLs being matched to unrelated routes (e.g. /group/new
)
Upvotes: 2
Views: 5125
Reputation: 7719
I finally managed to resolve the issue by using the private route pattern.
Upvotes: 1
Reputation: 281626
As per the documentation:
A
match
object contains information about how a matched the URL. match objects contain the following properties:params - (object) Key/value pairs parsed from the URL corresponding to the dynamic segments of the path isExact - (boolean) true if the entire URL was matched (no trailing characters) path - (string) The path pattern used to match. Useful for building nested <Route>s url - (string) The matched portion of the URL. Useful for building nested <Link>s
while
Locations represent where the app is now, where you want it to go, or even where it was.
so if you are on say /group/new
, location.pathname
will give you /group/new
whereas match.path
will give your the Route path defined for the component in which you log it if it is matched
Upvotes: 2