React + Redux:TypeError:无法读取未定义的属性“ push”

时间:2018-09-10 23:51:40

标签: reactjs redux

我从ReactJS和Redux开始,最近几天,当我在浏览器中打开我的应用一段时间后又回到它上面时,我陷入了一个问题:我看到了这个错误: enter image description here

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 个答案:

答案 0 :(得分:1)

您应该使用

withRouter(connect(...)(MyComponent))

而不是

connect(...)(withRouter(MyComponent))

这是documentation

因此,您认为示例中的this.props.historyundefined

答案 1 :(得分:0)

确保传递给logoutUser函数的对象没有未定义,并且以正确的方式接收了history参数。您试图在history对象上调用push方法,但是在这种情况下,它告诉您找不到函数,因为history是未定义的。希望这会有所帮助。

相关问题