React Component doesn't load even if I write exact path in the browser as defined in the routes

Viewed 497

I'm a beginner in React and stuck with some problems. As I have defined my routes into 3 specific Components. Please find them below.

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom';
import {Provider} from 'react-redux';
import store from './Redux/store';

ReactDOM.render(
  <Provider store={store}>
  <BrowserRouter >
    <App />
  </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);

App.js

//import logo from './logo.svg';
import './App.css';
import SignupAndSignInComponent from './Components/Sign-In and Sign-Up Component/Sign-in.and.signup.component';
import {Route,Switch} from 'react-router';
//import Menu from './Components/Menu-Component/menu.component';
//import sideNavBar from './Components/SideNavBar Component/Sidenavbar.component';
import Admin from './Components/Admin-Component/admin.component';
function App() {
  return (
   
    <Switch>
      <Route exact path="/" component={SignupAndSignInComponent}/>
      <Route path="/admin" component={Admin} />

      </Switch>
 
  );
}

export default App;

admin.component.jsx

import React from 'react';
import { Route } from 'react-router-dom';
//import Employees from '../Employees/employees.component';
import {Switch} from 'react-router-dom';
import Menu from '../Menu-Component/menu.component';
//import EmployeeEdit from '../EmployeeEdit/employeeEdit.component';
import LeaveTypeEdit from '../LeaveTypeEdit/leaveTypeEdit.component';
import LeaveTypes from '../LeaveTypes/leavetypes.component';
import Department from '../Department/department.component';
import DepartmentEdit from '../DepartmentEdit/departmentEdit.component';
import EmployeeRouteComponent from '../EmployeeRoute-Component/employeeroute.component';
//<Route  path={`${match.path}/employees/edit/:email`} component={EmployeeEdit} />
//<Route  path={`${match.path}/employees/edit`} component={EmployeeEdit} />

const Admin = ({ match }) => (
  <div className='shop-page'>
      <Menu/>
      <Switch>
        <Route exact path={`${match.path}/employees`} component={EmployeeRouteComponent} />
        <Route exact path={`${match.path}/leavetypes`}  component={LeaveTypes}/>
        <Route path={`${match.path}/leavetypes/edit/:leave_id`}  component={LeaveTypeEdit}/>
        <Route exact path={`${match.path}/department`} component={Department} />
        <Route  path={`${match.path}/department/edit/:department_id`} component={DepartmentEdit} />
        <Route  path={`${match.path}/department/edit`} component={DepartmentEdit} />
       </Switch>
  </div>
);

export default Admin;

employeeroute.component.jsx

import React from 'react';
import Employees from '../Employees/employees.component'; 
import EmployeeEdit from '../EmployeeEdit/employeeEdit.component';
import { Route } from 'react-router-dom';
import {Switch} from 'react-router-dom';
import {withRouter} from 'react-router-dom';

const EmployeeRouteComponent=({ match })=> 
 {
     console.log("kjsdj",match.path);
       return(
         <Switch>
               <Route exact path={`${match.path}/data`} component={Employees} />
               <Route path={`${match.path}/data/edit/:email`} component={EmployeeEdit} />
               <Route path={`${match.path}/data/edit`} component={EmployeeEdit} />
        </Switch> 
    );

 }
export default withRouter(EmployeeRouteComponent);

employees.component.jsx

import axios from 'axios';
import React, { useEffect,useState } from 'react';
import './employees.styles.scss';
import EmployeeDetails from '../EmployeeDetails/employeedetails.component';
import CustomButton from '../Custom-Button-Component/custom-button.component';
//import {withRouter} from 'react-router-dom';
import {connect} from 'react-redux';
import setEmployees from '../../Redux/Action/employees.action';

const Employees=(props)=>
{
    //const[employeeData,setEmployeeData]=useState(null);

    useEffect(
        async()=>{
          
         
            const response=await axios.get("http://localhost:8080/api/v1/employeedetails");
            const data=response.data;
            console.log(data);
            props.setEmployees(data);
          
         
        },
   [JSON.stringify(props.employees)] );
//cellpadding="0" cellspacing="0"

   console.log(props.employees);
    return (
        <section className="table-responsive">
           <h3 style={{color: "red"}}>{props.message}</h3>
        <h1>Employee Details</h1>
        <CustomButton onClick={()=>props.history.push(props.match.path+"/edit/-1")}>Add Employee</CustomButton>
        <div className="tbl-header">
          <table  border="0">
            <thead>
              <tr>
                <th>EmailId</th>
                <th>UserType</th>
                <th>Department</th>
                <th>Reporting</th>
                <th>Designation</th>
                <th>PhoneNumber</th>
                <th>Action</th>
              </tr>
            </thead>
          </table>
        </div>
        <div className="tbl-content">
          <table  border="0">
            <tbody>
            {props.employees?props.employees.map(employee=><EmployeeDetails key={props.employees.email_id}
            email_id={employee.email_id}
            department={employee.department}
            designation={employee.designation}
            phone_number={employee.phone_number}
            reporting={employee.reporting}
            user_type={employee.user_type}

             />):<EmployeeDetails/>}
           </tbody>
          </table>
         </div>  
        </section> 
    );

    
}
const mapStateToProps=(state)=>({
   message:state.login.message,
   employees:state.login.employees
});

const mapDispatchToProps=(dispatch)=>({
   setEmployees:employees=>dispatch(setEmployees(employees))
})

export default connect(mapStateToProps,mapDispatchToProps)(Employees);

And as you can see I have defined Employee Component route as "http://localhost:3000/admin/employees/data" but still, it doesn't load the component and can't even log anything when I routes to this specific route. But everything is working fine when I'm accessing all the routes defined in the "Admin Component" but not able to access the routes defined in the "EmployeeRoute" component. Please let me know if anything is missing from my side.

1 Answers

The problem is in the way that you have your various Switch blocks rendered relative to one another. Specifically it's due to using exact incorrectly.

Let's think about how we expect the /admin/employees/data path to find it's component. You have this statement here:

<Route exact path={`${match.path}/data`} component={Employees} />

inside of an EmployeeRouteComponent.

That EmployeeRouteComponent is loaded from inside Admin here:

<Route exact path={`${match.path}/employees`} component={EmployeeRouteComponent} />

But you are only loading EmployeeRouteComponent if the url is an exact match to "/admin/employees/". Your URL "/admin/employees/data" is not an exact match so it skips over this condition. It looks through all of the possibilities in Admin and finds no match, so it renders a div with a Menu and no contents.

You need to remove the exact from your Route and I would remove all of your other exacts while you're at it. Instead put more specific URLs before shorter ones (as the router will select the first match). For example, if you move your Admin route before your SignupAndSignInComponent, any URL which does not start with "/admin" will load the sign-up.

Related