Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Router Switch did not work properly

Tags:

I am new to react and trying to create simple navigation which has two menu items (Dashboard and Users). But when I click on Users link it did not render that page content, but dashboard content getting hide. Someone please help me to resolve the issue.

App.js

import React, { Component } from 'react';
import Login from './pages/Login';
import { BrowserRouter as Router, Switch, Route, Link, Redirect, withRouter } from 'react-router-dom';

import { history } from './_helpers/history';
import { authenticationService } from './_services/authentication.service';
import Users from './pages/users/Users';
import Dashboard from './pages/Dashboard';


class App extends Component {

  constructor(props) {
    super(props);

    this.state = {
        currentUser: null
    };
  }


  componentDidMount() {
      authenticationService.currentUser.subscribe(x => this.setState({ currentUser: x }));
  }

  logout() {
      authenticationService.logout();
      history.push('/login');
  }



  render () { 
    const { currentUser } = this.state;
    return (
      currentUser ? (

        <Router>
        <div id="wrapper">  
           <ul>
        <li><Link to={'/'} className="nav-link" > <i className="fas fa-fw  fa-tachometer-alt"></i> <span>Dashboard</span> </Link></li>
          <li><Link to={'/users'} className="nav-link" > <i className="fas fa-fw fa-users"></i> <span>Users</span> </Link></li>
        </ul>

          <Switch>
              <Route path='/' component={Dashboard} />
              <Route path='/users' component={Users} />
          </Switch>

          </div>



      </Router>
      ) : <Login />
  );
 }
}

export default App;

Dashboard.js

import React, { Component } from 'react';
import { Formik, Field, Form, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import { authenticationService } from '../_services/authentication.service';
import { history } from '../_helpers/history';


class Dashboard extends Component {

  constructor (props){
    super(props);

    if (authenticationService.currentUserValue) { 
      history.push('/');
    }

    this.state = {
        isPage: '/'
    }    

  }

    render (){
        if(this.state.isPage == window.location.pathname){
            return (    
                <div className="container">
                    dashboard
                </div>
            )
        }else{
            return '';
        }
    }

  }


export default Dashboard;

Users.js

import React, { Component } from 'react';
import { Formik, Field, Form, ErrorMessage } from 'formik';
import * as Yup from 'yup';
import { authenticationService } from '../../_services/authentication.service';
import { history } from '../../_helpers/history';


class Users extends Component {

  constructor (props){
    super(props);

    if (authenticationService.currentUserValue) { 
      history.push('/');
    }

    this.state = {
        isPage: '/users'
    }

  }

    render (){
        if(this.state.isPage == window.location.pathname){
            return (    
                <div className="container">
                    users
                </div>
            )
        }else{
            return '';
        }

    }

  }


export default Users;
like image 329
Mak Avatar asked Oct 14 '19 01:10

Mak


People also ask

How does Switch work react router?

The switch component looks through all of its child routes and it displays the first one whose path matches the current URL. This component is what we want to use in most cases for most applications, because we have multiple routes and multiple plate pages in our app but we only want to show one page at a time.

Why Switch is not there in react router Dom?

Conclusion # To solve the error "export 'Switch' (imported as 'Switch') was not found in 'react-router-dom'", import Routes instead of Switch and wrap your <Route /> components with a <Routes> component, e.g. <Routes><Route path="/about" element={<About />} /></Routes> .

Is react router v6 stable?

React Router v6 received a stable release on November 3, 2021. This version is half the size of the previous one and has much better support for hooks.


2 Answers

In App.js component; make Switch direct child of Router; that will fix the issue. You can refactor your code like so:

<Router>
    <Switch>
        <div id="wrapper">  
            <ul>
                <li><Link to={'/'} className="nav-link" > <i className="fas fa-fw  fa-tachometer-alt"></i> <span>Dashboard</span> </Link></li>
                <li><Link to={'/users'} className="nav-link" > <i className="fas fa-fw fa-users"></i> <span>Users</span> </Link></li>
            </ul>

            <Route path='/' component={Dashboard} />
            <Route path='/users' component={Users} />
        </div>
    </Switch> 
</Router>
like image 82
Emeka Augustine Avatar answered Oct 12 '22 20:10

Emeka Augustine


but dashboard content getting hide.

Can you elaborate on that? I'm not quite understanding what you mean.

The problem may lie with your use of react lifecycles. authenticationService.currentUser.subscribe() is set on componentDidMount() so only after the JSX gets mounted to the DOM. Your Users component is checking authenticationService.currentUserValue on the constructor which runs first before it gets mounted. authenticationService.currentUserValue maybe giving you a falsy which will kick you out to /. Console log that value or place those inside a componentDidMount so it will only check after the mount.

constructor (props){
    super(props);

    this.state = {
        isPage: '/users'
    }
  }

  componentDidMount() {
     if (authenticationService.currentUserValue) { 
      history.push('/');
    }
  }
like image 45
Cecil John Tantay Avatar answered Oct 12 '22 22:10

Cecil John Tantay