Ale
Ale

Reputation: 236

How to render nested routing in ReactJs

I'm developing a ReactJS webapp with route component. The site has a login page, and a dashboard. The dashboard has a navbar and a main section.

App.js

class App extends React.Component {
render() {
    return (
        <div style={{height: "100%"}} className="App">
            <Router>
                <Switch>
                    <Route path="/" exact strict component={Dashboard}/>
                    <Route path="/login" exact strict component={Login}/>
                </Switch>
            </Router>
        </div>
    );
}
}

Dashboard.js

class Dashboard extends Component {
state = {
    sideDrawerOpen: false,
    redirect: false
};
drawerToggleClickHandler = () => {
    this.setState((prevState) => {
        return {sideDrawerOpen: !prevState.sideDrawerOpen};
    });
};

render() {

    return (
        <div style={{height: "100%"}} className="App">
            <Toolbar drawerClickHandler={this.drawerToggleClickHandler}/>                
            <main style={{marginTop: '63px'}}>
                    <div>
                        <Switch>
                            <Route exact path="/" render={
                                () => {
                                    return (<div>
                                        Welcome home about
                                    </div>);
                                }}/>

                            <Route exact path="/about" render={
                                () => {
                                    return (<div>
                                        Welcome About
                                    </div>);
                                }
                            }/>
                        </Switch>
                    </div>
            </main>
        </div>
    );
}
}

Toolbar.js

class Toolbar extends Component {
constructor(props) {
    super(props);
    this.state = {
        loggedIn: false,
        redirect: false
    };
    this.logoutClickHandler = this.logoutClickHandler.bind(this);
}


loginHandle() {
    this.setState(prevState => ({
        loggedIn: !prevState.loggedIn
    }))
}

logoutClickHandler() {
    this.setState(prevState => ({
        loggedIn: !prevState.loggedIn
    }));
    // console.log("Logout clicked");
    sessionStorage.setItem('userData', '');
    sessionStorage.clear();
    this.setState({redirect: true});
}

componentDidMount() {
    if (sessionStorage.getItem('userData')) {
        console.log("User logged");
    } else {
        this.setState({redirect: true});
    }
}

render() {
    if (this.state.redirect) {
        return (<Redirect to={'/login'}/>);
    }
    return (
        <header className="toolbar">
                <nav className="toolbar__navigation">
                    <div className="toolbar__logo">
                        <NavLink to="/" exact strict>The Logo</NavLink>
                    </div>
                    <div className="spacer"/>
                    <div className="toolbar__navigation-items">
                        <ul>
                            <li>
                                <NavLink to="/about" activeStyle={
                                    {color: 'green'}
                                }>About</NavLink>
                            </li>

                            <li>
                                <Link to={'/'} onClick={this.logoutClickHandler}>Salir</Link>
                            </li>
                        </ul>
                    </div>                      
                </nav>
        </header>
    );
}
}

The workflow is: User logged into login page and redirect to dashboard, that work perfectly but I expect when I click on NavLink "About" in main section in Dashboard, render about page, but didn't happen.

Upvotes: 0

Views: 144

Answers (1)

Muljayan
Muljayan

Reputation: 3886

You have to set all the routes at the start. In order to

 <Router>
        <Switch>
           <Privateroute path="/" exact strict component={Dashboard}/>
           <Privateroute path="/about" exact strict component={ABOUT_PAGE_COMPONENT}/>
           <Route path="/login" exact strict component={Login}/>
        </Switch>`enter code here`
    </Router>

In order to protect your routes consider using a private component where you do the authentication check in the render method of the route. Something like what is given below.

PrivateRoute.js file

import React from 'react';
import { Route, Redirect } from 'react-router-dom';


const PrivateRoute = (props) => {
  const { auth, component: Component, ...rest } = props;
  const { isAuthenticated } = auth;
  return (
    <Route
      {...rest}
      render={() =>
        isAuthenticated ? (
          <>
            <ToolBar />
              <Component />
            //<FooterComponents />
          </>
        ) : (
            <Redirect
              to="/"
            />
          )
      }
    />
  )
}

export default PrivateRoute;

Upvotes: 1

Related Questions