Home > Mobile >  TypeError: Cannot read properties of undefined (reading 'push') in React Js
TypeError: Cannot read properties of undefined (reading 'push') in React Js

Time:11-22

I want to navigate to a new page when clicking on a button. I used history but it not working. here is my index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router} from 'react-router-dom';
import history from './history';

ReactDOM.render(
  <Router history={history}>
        <App/>
    </Router>,
  document.getElementById('root')
);

reportWebVitals();

here is App.js file

import React from 'react';
import logo from './logo.svg';
import './App.css';
import {Router, Route,Routes} from 'react-router-dom'
import EmployeeList from './pages/employeeList';
import AddEmployee from './pages/addEmployee';
import ViewEmployees from './pages/viewEmployees';
import Header from './components/header/Header';
import NavigationBar from './components/Navigation';
import Footer from './components/footer/footer';


function App() {
  return (
    <div>
       <NavigationBar/>
    <div className="container-fluid">
               
               
                <div className="app-main">
                 
                    <Routes> 
                    
                         
                          <Route path = "/employeeList" element={<EmployeeList/>}></Route>
                          <Route path = "/addEmployee/:id" element={<AddEmployee/>}></Route>
                          <Route path = "/viewEmployee/:id" element={<ViewEmployees/>}></Route>
                         
                    </Routes>
                  
                   
                </div>
               
                
       </div>
       <div>
               <Footer/>
       </div>
    </div>
    
  );
}

export default App;

And I created history.js file also below you can see the code of my history.js

import { createBrowserHistory as history} from 'history';

export default history();

below you can see the page code.

import React, { Component } from 'react'
import EmployeeService from '../employeeServices'


class EmployeeList extends Component {
    constructor(props) {
        super(props)

        this.state = {
                employees: []
        }
        this.addEmployee = this.addEmployee.bind(this);
        this.editEmployee = this.editEmployee.bind(this);
        this.deleteEmployee = this.deleteEmployee.bind(this);
    }

    deleteEmployee(id){
        EmployeeService.deleteEmployee(id).then( res => {
            this.setState({employees: this.state.employees.filter(employee => employee.id !== id)});
        });
    }
    viewEmployee(id){
        this.props.history.push('/viewEmployee/${id}');
    }
    editEmployee(id){
        this.props.history.push('/addEmployee/${id}');
    }

    componentDidMount(){
        EmployeeService.getEmployees().then((res) => {
            this.setState({ employees: res.data});
            console.log(res.data);
        });
    }

    addEmployee(){
        this.props.history.push('/addEmployee/_add');
    }

    render() {
        return (
            <div>
                 <h2 className="text-center">Employees List</h2>
                 <div className = "row">
                    <button className="btn btn-primary" onClick={this.addEmployee}> Add Employee</button>
                 </div>
                 <br></br>
                 <div className = "row">
                        <table className = "table table-striped table-bordered">

                            <thead>
                                <tr>
                                    <th> Employee First Name</th>
                                    <th> Employee Last Name</th>
                                    <th> Employee Email Id</th>
                                    <th> Actions</th>
                                </tr>
                            </thead>
                            <tbody>
                                {
                                    this.state.employees.map(
                                        employee => 
                                        <tr key = {employee.id}>
                                             <td> {employee.firstName} </td>   
                                             <td> {employee.lastName}</td>
                                             <td> {employee.emailId}</td>
                                             <td>
                                                 <button onClick={ () => this.editEmployee(employee.id)} className="btn btn-info">Update </button>
                                                 <button style={{marginLeft: "10px"}} onClick={ () => this.deleteEmployee(employee.id)} className="btn btn-danger">Delete </button>
                                                 <button style={{marginLeft: "10px"}} onClick={ () => this.viewEmployee(employee.id)} className="btn btn-info">View </button>
                                             </td>
                                        </tr>
                                    )
                                }
                            </tbody>
                        </table>

                 </div>

            </div>
        )
    }
}

export default EmployeeList

when I click the add employee button error will show as

**TypeError: Cannot read properties of undefined (reading 'push')**

how can I overcome this error?

CodePudding user response:

For react-router-dom version 6:

You need to use useNavigate instead.

For functional component:
You can just use it as hooks normally and just use in it.

import { useNavigate } from 'react-router-dom';
function MyComponent(){
  const navigate = useNavigate();

  useEffect(() => {
     navigate('/to-your-url');
  }, [something]);
}

For class based component, you need to use a functional component wrapper, here I call it WithNavigate:


import React from 'react';
import { useNavigate } from 'react-router-dom'
class MyComponent extends React.Component {
    doSomething(){
      this.props.navigate('/to-your-url');
    }
    render(){
        return(
            <header className='todo-header'>
                <h1 onClick={this.doSomething}>Todo List Saya</h1>
            </header>
        )
    }
}

function WithNavigate(props){
    const navigate = useNavigate();
    return <MyComponent {...props} navigate={navigate}/>
}
export default WithNavigate;

CodePudding user response:

As i can see you are using class based function so i suggest use withRouter hope it is helpful see below link for more information.

https://v5.reactrouter.com/web/api/withRouter

  • Related