Доброго времени суток!
Помоги пожалуйста решить проблемку.
Я реализовал Авторизацию по
этому туториалу.
Все работает правильно, плавно, но есть одна упущенная ошибка автором. В App.js помимо setToken, токен проверяется на срок действие, и если токен уже устарел, то просто диспатчится logout().
Проблема в том, что появляется ошибка: Cannot read property 'push' of undefined .
Но если в меню нажать на кнопку logout, то все работает как надо.
Смотрите, ниже есть код.
App.jsimport 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;
Menu.js (Здесь все работает)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))
auth.js (здесь живет logoutUser())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')
}
Посмотрите, пожалуйста. Сколько я не пытался, у меня ничего не вышло. Я новенький в Redux, не очень понимаю, что и в какой ситуации что происходит.Заранее большое спасибо!