React + Redux:TypeError:无法读取未定义的属性“push”
2018-09-10
1330
我开始使用 ReactJS 和 Redux,最近几天,我遇到了一个问题,当我在浏览器中打开应用程序一段时间然后返回时,我看到了此错误:
TypeError: Cannot read property 'push' of undefined
它在这里,在我的
Event.js
组件中:
import React, { Component } from 'react';
import axios from 'axios';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { registerUser, logoutUser } from '../redux/actions/authentication';
import { withRouter } from 'react-router-dom';
class Event extends Component {
constructor() {
super();
this.state = {
...
}
UNSAFE_componentWillMount() {
if(!this.props.auth.isAuthenticated) {
console.log('Unauthorized - Event action');
this.props.history.push('/');
}
}
componentDidMount() {
axios.get('/api/events')
.then((response) => {
this.setState({events: response.data});
console.log('events: ', this.state.events);
}).catch(err => {
console.log('CAUGHT IT! -> ', err);
});
}
componentWillReceiveProps(nextProps) {
if(nextProps.errors) {
this.setState({
errors: nextProps.errors
});
}
}
...
render() {
const { errors } = this.state;
const {isAuthenticated, user} = this.props.auth;
return (...)
}
Event.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(mapStateToProps,{ registerUser })(withRouter(Event))
然后,我的
redux/actions/authentication.js
看起来像这样:
import axios from 'axios';
import { GET_ERRORS, SET_CURRENT_USER } from './types'; // we list here the actions we'll use
import setAuthToken from '../../setAuthToken';
import jwt_decode from 'jwt-decode';
export const registerUser = (user, history) => dispatch => {
axios.post('/api/users/register', user)
.then(res => history.push('/login'))
.catch(err => {
dispatch({
type: GET_ERRORS,
payload: err.response.data
});
});
}
export const loginUser = (user) => dispatch => {
axios.post('/api/users/login', user)
.then(res => {
//console.log(res.data);
const { token } = res.data;
localStorage.setItem('jwtToken', token);
setAuthToken(token);
const decoded = jwt_decode(token);
dispatch(setCurrentUser(decoded));
})
.catch(err => {
dispatch({
type: GET_ERRORS,
payload: err.response.data
});
});
}
export const setCurrentUser = decoded => {
return {
type: SET_CURRENT_USER,
payload: decoded
}
}
export const logoutUser = (history) => dispatch => {
localStorage.removeItem('jwtToken');
setAuthToken(false);
dispatch(setCurrentUser({}));
history.push('/login');
}
和减速器 -
authReducer.js
:
import { SET_CURRENT_USER } from '../actions/types';
import isEmpty from '../../validation/is-empty';
const initialState = {
isAuthenticated: false,
user: {}
}
export default function(state = initialState, action) {
switch(action.type) {
case SET_CURRENT_USER:
return {
...state,
isAuthenticated: !isEmpty(action.payload),
user: action.payload
}
default:
return state;
}
}
errorReducer.js
如下所示:
import { GET_ERRORS } from '../actions/types';
const initialState = {};
export default function(state = initialState, action ) {
switch(action.type) {
case GET_ERRORS:
return action.payload;
default:
return state;
}
}
和
index.js
:
import { combineReducers } from 'redux';
import errorReducer from './errorReducer';
import authReducer from './authReducer';
export default combineReducers({
errors: errorReducer,
auth: authReducer
});
在 nabber 菜单中,我有一个链接用于注销用户。如果用户单击该链接,我会像这样注销他:
onLogout(e) {
e.preventDefault();
this.props.logoutUser(this.props.history);
}
但是,我仍然无法弄清楚为什么会看到上述错误。我在这里也不明白的是,当我看到该错误屏幕然后刷新页面时,错误页面会消失,并且我会从
localhost:3000/events
重定向到
localhost:3000
。
2个回答
您应该使用
withRouter(connect(...)(MyComponent))
而不是
connect(...)(withRouter(MyComponent))
这里是 文档
因此,我认为您的示例中的
this.props.history
是
undefined
。
Olivier Boissé
2018-09-11
确保传递给
logoutUser
函数的对象未定义,并且
history
参数以正确的方式接收。您正尝试在
history
对象上调用推送方法,但在这种情况下,它会告诉您无法找到该函数,因为
history
未定义。希望这能有所帮助。
Dimitrih
2018-09-11