2

Say i have 2 components called <Dashboard/> that is being rendered after a user logged in and <Landing/> that is being rendered when user is not logged in yet In reactjs, what should i do if i want to use the same / route that if the user is not logged in yet it will render <Landing/> and it will render <Dashboard/> if the user is logged in?

<Landing/> is

<Route path="/" component={Landing} onEnter={appOnEnter}>
  <IndexRoute component={Home}/>

  ... Other not-login-required routes ...
</Route>

and Dashboard is

<Route path="/" component={Dashboard} onEnter={appOnEnter}>
  <IndexRoute component={Home} />

  ... Other login-required routes ...
</Route>

i came accross getComponent/getComponents which i think i can use like

<Route path="/" getComponent={(nextState, cb) => {
 // do asynchronous stuff to find the components
 cb(null, Course)
}} />

But this doesn't seem to suggest using that method

The reason we don't explicitly support this sort of pattern is because it's fairly atypical to wire things up this way

So what would be the best way to achieve what i want?

Community
  • 1
  • 1
littlechad
  • 1,202
  • 17
  • 48

3 Answers3

7

You can make a Home component for that route, and

return this.props.loggedIn ? <Dashboard /> : <Login />;

That way you don't have to deal with it at the route level.

Andy_D
  • 4,112
  • 27
  • 19
1

even though works, the answer that @Andy_D posted doesn't actually meet my use case, so i ended up doing it this way

...

/** 
 * Layouts 
 * 
 * i separate the main layout into two parts
 * - Guest, base layout used to any page or route for guests
 * - Member, base layout used to any page or route for members
*/
import Guest from './Layouts/Guest'
import Member from './Layouts/Member'

...

const Routesz = (store, actions) => {
  const GuestRoute = () => (
    <Route path="/">
      <Route component={Guest.components.Layout}>
        <Route
          path="/signin"
          component={SigninComponent}
        />
        <Route
          path="/signup"
          component={SignupComponent}
        />
      </Route>
    </Route>
  )

  const MemberRoute = () => (
    <Route path="/">
      <Route component={Member.components.Layout}>
        <IndexRoute component={DashboardComponent}/>

        <Route path="post" component={SomeParentComponent} name="Service">
          <IndexRoute
            component={SomeChildComponent_1}
          />
          <Route
            path="add"
            component={SomeChildComponent_2}
          />
          <Route
            path=":id/edit"
            component={SomeChildComponent_3}
          />
          <Route
            path=":id/remove"
            component={SomeChildComponent_4}
          />
        </Route>
      </Route>
    </Route>
    )

  const MainRoutes = () => (
    isAuthorized()
      ? MemberRoute(actions)
      : GuestRoute(actions)
  )

  return MainRoutes(actions)
}

export default (store) => {
  return (
    <Route>
      {Routesz(store, actions)}
      ...
    </Route>
  )
}

Currently this is flexible enough for me to use different layouts for different pages

littlechad
  • 1,202
  • 17
  • 48
1

This might be helpful for someone looking for an answer.

In the react router you can use render() to return the component which allows for convenient inline rendering and wrapping without the undesired remounting.

Since it's a function, you can do a condition check to decide which component should get render and return that component.

The best part is you can do this inline without creating a new component.

ReactDOM.render(
    <Router>
        <Route path="/home" render={() => {
             return isDashBoard ? <Dashboard /> : <Landing />
        } />
    </Router>,
   node
);

Basically it's simple inline JSX to determine which component to be returned.

Shashith Darshana
  • 2,715
  • 1
  • 25
  • 27