rahul
rahul

Reputation: 7663

Not able to set Routes dynamically React-Router

I am trying to create routes dynamically based on login user type. This is my code:

createRoute(){
    var allRoutes = [];
    if(this.props.userType === "admin"){
      allRoutes.push((<Route path="Login" component={Login} />));
      allRoutes.push((<Route path="Dashboard" component={AdminDashboard} />));
      allRoutes.push((<Route path="UserManagement" component={UserManagement} />));
      allRoutes.push((<Route path="ResourceManagement" component={ResourceManagement} />));
      allRoutes.push((<Route from='*' to='Dashboard' />));
    }
    else if(this.props.userType === "user"){
      allRoutes.push((<Route path="Login" component={Login} />));
      allRoutes.push((<Route path="Dashboard" component={UserDashboard} />));
      allRoutes.push((<Route from='*' to='Dashboard' />));
    }
    else{
      allRoutes.push((<Route path="Login" component={Login} />));
      allRoutes.push((<Route from='*' to='Login' />));
    }
    return allRoutes;
  }

and this is how I am rendering those

render(){
    return (
      <div className="contentArea">
        <Router history={hashHistory}>
          <Route path="/">
            {this.createRoute()}
          </Route>
        </Router>
      </div>
    );
  }

Now suppose if I login with admin user for the first time it is showing the related page properly.

But when I logout and login with normal user it still shows the admin page, until I refresh the whole page.

In short Routes are not getting immediately when different type of users are login in, until we refresh the page.

Can any one please tell me what I am doing wrong here.

Thanks in advance.

Upvotes: 2

Views: 121

Answers (1)

JJJ
JJJ

Reputation: 3332

But when I logout and login with normal user if still shows the admin page, until I refresh the whole page.

You need to use componentWillReceiveProps. This will update the component when you login with a new user because you will be passing new props to it.

Knowing this, I would re-structure my code to be able to pass new props to it. This is how I would re-structure createRoute:

createRoute(userType){
  var allRoutes = [];
  if(userType === "admin"){
    allRoutes.push((<Route path="Login" component={Login} />));
    allRoutes.push((<Route path="Dashboard" component={AdminDashboard} />));
    allRoutes.push((<Route path="UserManagement" component={UserManagement} />));
    allRoutes.push((<Route path="ResourceManagement" component={ResourceManagement} />));
    allRoutes.push((<Route from='*' to='Dashboard' />));
  }
  else if(userType === "user"){
    allRoutes.push((<Route path="Login" component={Login} />));
    allRoutes.push((<Route path="Dashboard" component={UserDashboard} />));
    allRoutes.push((<Route from='*' to='Dashboard' />));
  }
  else{
    allRoutes.push((<Route path="Login" component={Login} />));
    allRoutes.push((<Route from='*' to='Login' />));
  }

  this.setState({routes: allRoutes});
}

As you can see, I passed an argument to createRoute instead of the actual prop value so we can reuse it later with the new props. Also, instead of returning the array of routes, I am setting the components state.

Now we will render the routes using the state:

render(){
return (
  <div className="contentArea">
    <Router history={hashHistory}>
      <Route path="/">
        {this.state.routes}
      </Route>
    </Router>
  </div>
  );
  }

We will now call createRoutes inside componentDidMount:

componentDidMount(){
  this.createRoutes(this.props.userType)
}

Finally, we will use componentWillReceiveProps to update the component when you login with a new user:

componentWillReceiveProps(newProps){
  //check if props are in fact new
  if(newProps.userType !== this.props.userType){
    //create new routes
    this.createRoutes(newProps.userType)
  }
}

Upvotes: 1

Related Questions