3

My react component looks like this:

 class App extends React.Component {  
  render() {
    debugger;
    if(!this.props.isUserExist) {
      return (
        <div>
          <Route exact path="/" component={DashboardPage} />
        </div>
      );
    }
    return (
      <div>
        <Switch>
          <Route exact path="/" component={HomePage} />
          <Route exact path="/list" component={ListPage} />
          <Route component={NotFoundPage} />
        </Switch>
      </div>
    );
  }
}

My question is: is there a better way to check these conditions with react router v4? is this the best way to check these conditions? Is this the best practice? Please someone help me with this!

Dayan
  • 611
  • 3
  • 12
  • 24
  • 1
    Possible duplicate of [Simple Conditional Routing in Reactjs](https://stackoverflow.com/questions/48497510/simple-conditional-routing-in-reactjs) – John Samuel May 25 '18 at 10:19
  • thanks @johnsam, what if i want to send route to different componets. for example, when user exist and when user not existing ? – Dayan May 25 '18 at 10:22
  • happy coding :D – John Samuel May 25 '18 at 10:23
  • @johnsam, hope you understand the question? – Dayan May 25 '18 at 10:24
  • is this the proper way? – Dayan May 25 '18 at 10:26
  • 1
    Dayan. In your example, you could just use a ternary condition in your case. ``````. Your case is not inside the switch, and will not follow the fallback rules towards notfound page for logged in users. For more complex scenarios check the answer below. – Vlatko Vlahek May 25 '18 at 10:36
  • Please guys, don't down vote the question. it could be a silly question for someone, but not for me. I'm still a beginner and trying to meet deadlines at work. Anyway thanks everyone for the help. – Dayan May 26 '18 at 05:34

2 Answers2

7

In a simpler way for individual paths, you can go with,

<Route exact path="/" component={()=>this.props.isUserExist?<HomePage/> : <Dashboard/>} />
Rohith Murali
  • 4,864
  • 2
  • 18
  • 23
  • Why should be do that? – Rob May 25 '18 at 11:48
  • I mean, it can be done this way too... The condition can be provided just before the component selection. – Rohith Murali May 25 '18 at 11:52
  • @RohithMurali I tried this but it is showing `Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.` but the component gets rendered when passed as component prop. – PrivateOmega Jul 12 '19 at 09:24
  • @PrivateOmega Are you sure you have done like, `component={()=>this.props.isUserExist? : }` and not `component={this.props.isUserExist? : }`. Because the error itself says `expected a string or a class/function` – Rohith Murali Jul 12 '19 at 09:29
  • @RohithMurali yes, the condition check is inside a function. `render={() => currentUser.roles.includes('admin') ? : }` I dont see any problem with this. – PrivateOmega Jul 12 '19 at 09:44
  • 1
    @PrivateOmega `render`?? – Rohith Murali Jul 12 '19 at 17:56
  • Oh damn I didn't notice that huge difference. So how is it different?. Thanks man – PrivateOmega Jul 12 '19 at 17:57
4

In short, React Router isn't built with a custom solution for this scenario. It's lightweight enough to let the developer decide what would be the better option.

Long story, it depends. If you expect the code to have to have common routes, which it doesn't in this example, it might be more maintainable to use inline Javascript and operator (&&). For example:

class App extends React.Component {  
  render() {
    return (
      <div>
        <Switch>
          {this.props.isUserExist && 
          <Route exact path="/" component={HomePage} />
          <Route exact path="/list" component={ListPage} />
          }
          <Route exact path="/dashboard" component={DashboardPage} />
          <Route component={NotFoundPage} />
        </Switch>

      </div>
    );
  }
}

In the scope of this example, (Dashboard only accessible to logged out users, not found page is only accessible to logged in users) your example is demonstrating the concept early return, which is a good pattern. It's a way to avoid writing else and to signal what the main code path is (user authenticated) and what the occasional code path is (user isn't authenticated). Read more about the early return here.

There are also other ideas around this, such as building your own custom PrivateRoute. An example of this idea is demonstrated here.

Karamell
  • 932
  • 6
  • 19