Answer the question
In order to leave comments, you need to log in
Error: Cannot read property 'push' of undefined how to solve?
Good day!
Please help me solve the problem.
I implemented Authorization according to this tutorial.
Everything works correctly, smoothly, but there is one missed mistake by the author. In App.js, in addition to setToken, the token is checked for validity, and if the token is already out of date, then logout () will simply be dispatched.
The problem is that an error appears: Cannot read property 'push' of undefined .
But if you click on the logout button in the menu, then everything works as it should.
See below is the code.
app.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './store';
import jwt_decode from 'jwt-decode';
import setAuthToken from './setAuthToken';
import { setCurrentUser, logoutUser } from './actions/authentication';
import Navbar from './components/Navbar';
import Register from './components/Register';
import Login from './components/Login';
import Home from './components/Home';
import 'bootstrap/dist/css/bootstrap.min.css';
if(localStorage.jwtToken) {
setAuthToken(localStorage.jwtToken);
const decoded = jwt_decode(localStorage.jwtToken);
store.dispatch(setCurrentUser(decoded));
const currentTime = Date.now() / 1000;
if(decoded.exp < currentTime) {
store.dispatch(logoutUser());
window.location.href = '/login'
}
}
class App extends Component {
render() {
return (
<Provider store = { store }>
<Router>
<div>
<Navbar />
<Route exact path="/" component={ Home } />
<div className="container">
<Route exact path="/register" component={ Register } />
<Route exact path="/login" component={ Login } />
</div>
</div>
</Router>
</Provider>
);
}
}
export default App;
import React, { Component } from "react";
import {Link} from "react-router-dom";
import { connect } from "react-redux"
import { withRouter } from "react-router-dom"
import PropTypes from "prop-types"
import {logoutUser} from "../actions/authentication";
class Menu extends Component {
onLogout(e) {
e.preventDefault()
this.props.logoutUser(this.props.history)
}
render() {
const {isAuthenticated, user} = this.props.auth
const authLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<a className="nav-link" href="#" onClick={this.onLogout.bind(this)}>Выйти</a>
</li>
</ul>
)
const guestLinks = (
<ul className="navbar-nav ml-auto">
<li className="nav-item">
<Link className="nav-link" to="/login">Войти</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/register">Регистрация</Link>
</li>
</ul>
)
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="#">StandCars</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item active">
<Link className="nav-link" to="/">Главная</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to="/cars">Cars</Link>
</li>
</ul>
{isAuthenticated ? authLinks : guestLinks}
</div>
</nav>
)
}
}
Menu.propTypes = {
logoutUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
}
const mapStateToProps = (state) => ({
auth: state.auth,
})
export default connect(mapStateToProps, {logoutUser})(withRouter(Menu))
import setAuthToken from "../common/setAuthToken"
import { GET_ERRORS, SET_CURRENT_USER } from "./types"
import axios from "axios"
import jwt from "jwt-decode"
export const registerUser = (user, history) => dispatch => {
axios.post('/api/auth/register', user).then(function (response) {
console.log(response);
history.push("/login")
})
.catch(function (error) {
console.log(error);
});
}
export const loginUser = (user) => dispatch => {
axios.post("/api/auth/login", user)
.then(response => {
console.log(response.data)
const { access_token } = response.data
localStorage.setItem("jwtToken", access_token)
setAuthToken(access_token)
const decoded_jwt = jwt(access_token)
dispatch(setCurrentUser(decoded_jwt))
}).catch(function (error) {
console.log(error)
})
}
export const setCurrentUser = (decoded_jwt) => {
return {
type: SET_CURRENT_USER,
payload: decoded_jwt,
}
}
export const logoutUser = (history) => dispatch => {
localStorage.removeItem("jwtToken")
setAuthToken(false)
dispatch(setCurrentUser({}))
history.push('/login')
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question