0

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.

1 Answer 1

1

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;
Sign up to request clarification or add additional context in comments.

2 Comments

Why put private route in App.js instead put only Dashboard route and keep about route inside Dashboard?
That way you dont have to do an authentication check on each of the protected pages individually. using a protected route would handle auth protection in one place. Also the last time i worked with react router i noticed that you cant nest the route components the way you have done in the question . It throws an error so this is the solution i was able to come up with and it worked flawlessly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.