Nikola Božić
Nikola Božić

Reputation: 147

React exact path in Route doesnt work as expected

Hi I have react app with login page and main page with routes in it. I have trouble understanding how path and exact path actually works with react router in this kind of situation ?

Here is my code of App component:

const PrivateRoute = ({ component: Component , ...rest }) => {
    const { userAuth, getUser } = useContext(AuthContext);
    return (
        <Route
            {...rest}
            render={props => !userAuth ? <Redirect to='/login' /> : <Component {...props} />}
        />
    )
}

function App(props) {
    return ( 
        <AuthState> 
            <Switch>
                <Route path='/login' component={SignIn} /> 
                <PrivateRoute exact path='/' component={MainPage} /> !!! // When i switch this to path only it works fine
            </Switch> 
        </AuthState>
    );
}

export default App;

And here is part of code of main component:

<main className={classes.content}>
    <div className={classes.toolbar} />
    <Switch>
        <Route path='/dataSets' component={DataSet} />
        <Route path='/dasboard' component={Dashboardmain} />
        <Redirect from='/' to='/dasboard' /> 
    </Switch>
</main>
</div>

So when I set like this:

<PrivateRoute exact path='/' component={MainPage} />

Routes /dasboard and dataSets are not rendered, just changed URL-s

But if I set like this:

<PrivateRoute path='/' component={MainPage} />

Everything works fine.

Any help understanding this kind of behavior?

Upvotes: 0

Views: 455

Answers (2)

Hải B&#249;i
Hải B&#249;i

Reputation: 2931

exact is a very helpful prop if you understand it. Basic you can understand it like this:

Let's use exact when you want user to go to exactly route (url) you want. If that route is a parent route and it has multiple child routes, don't use exact with the parent route, use it for children routes instead

In your example we can understand like this

  1. Remember we always have a route parent /

  2. Login is children of /, it doesn't contains any child route => so lets add exact for this route

  3. MainPage is a children of / too, but it is a parent of Dashboardmain and DataSet so DONT add exact for /

  4. Dashboardmain and DataSet are childrens of / but they aren't contain any child route => so lets add exact for them

The same logic with nested routes. You can create multiple nested routes with my explaination above. Good luck!

Upvotes: 1

Anil Singha
Anil Singha

Reputation: 428

Try like this in your App.js

<Router>
  <Route path="/login" component={MyLoginForm} />
  <PrivateRoute path="/onlyAuthorizedAllowedHere/" component={MyComponent} />
</Router>

And the PrivateRoute Component

import React from 'react'
import AuthService from './Services/AuthService'
import { Redirect, Route } from 'react-router-dom'

const PrivateRoute = ({ component: Component, ...rest }) => {

  // Add your own authentication on the below line.
  const isLoggedIn = AuthService.isLoggedIn()

  return (
    <Route
      {...rest}
      render={props =>
        isLoggedIn ? (
          <Component {...props} />
        ) : (
          <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
        )
      }
    />
  )
}

export default PrivateRoute

Upvotes: 1

Related Questions