Redux:TypeError:e未定义

时间:2018-06-04 15:24:05

标签: redux

https://github.com/reduxjs/redux/issues/3017

问题:当我在我使用connect方法的容器区域中使用调度包装动作创建者时发生 - 我遵循redux文档中的样式。

我正在使用redux和redux thunk。我正在尝试创建一个登录操作,到目前为止,当我发送一个动作时,它不起作用,该动作是另一个动作。

LoginContainer.js

import CONFIG from "../../../config";

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import {authenticateUser} from "../../../actions/authenticateUser";

import Login from '../../../components/views/login/Login'

import {store} from '../../../store';

function handleSubmit(e) {
    e.preventDefault();
    let calpersId = parseInt(e.target[0].value || e.target[1].value, 10) || 0;
    store.dispatch(authenticateUser(calpersId))
}

const mapStateToProps = (state) => {
    return {
        authentication: state.authentication
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        handleSubmit: (e) => {dispatch(handleSubmit(e))}
    }
}

const LoginContainer = connect(mapStateToProps, mapDispatchToProps)(Login);

export default LoginContainer;

authenticateUser.action.js

import CONFIG from '../config'

export const AUTHENTICATE_USER = 'AUTHENTICATE_USER'

export const initiateUserAuthentication = (token) => ({
    type: AUTHENTICATE_USER,
    token
})

export const AUTHENTICATATION_SUCCEEDED = 'AUTHENTICATATION_SUCCEEDED'

export const authenticatationSucceeded = (payload) => ({
    type: AUTHENTICATE_USER,
    payload
})


export const USER_ID_DOES_NOT_EXIST = 'USER_ID_DOES_NOT_EXIST'

export const userIdDoesNotExist = (uid) => ({
    type: USER_ID_DOES_NOT_EXIST,
    uid,
    message: "User id does not exist"
})

export function authenticateUser(id) {
    return function (dispatch) {
        let guidMap = {
            7103503579: "dad08fde-0ac1-404a-ba8a-cc7c76d5810f",
            6632408185: "6632408185-guid",
            6581985123: "6581985123-guid",
            1226290314: "a3908aa7-c142-4752-85ea-3741cf28f75e",
            4618604679: "4618604679-guid",
            6452522440: "6452522440-guid",
            3685610572: "3685610572-guid",
            5564535492: "5564535492-guid",
            5600493427: "5600493427-guid",
            3996179678: "3996179678-guid",
            7302651964: "7302651964-guid",
            3148148090: "3148148090-guid",
            5826752269: "5826752269-guid",
            6827859055: "6827859055-guid",
            1677401305: "1677401305-guid",
            2640602392: "dbed1af6-0fc9-45dc-96a3-ab15aa05a7a2",
            6474994805: "6474994805-guid"
        };
        let guid = guidMap[id]
        return fetch(CONFIG.API.MY_CALPERS_SERVER.LOCATION + 'ept/development/rest/simulatedAuth.json?guid=' + guid, {
            credentials: 'include'
        })
            .then(
                response => response.json(),
                error => console.log('An error occured.', error))
            .then(json => {
                document.cookie = "authentication=" + guid + "; max-age=" + (60 * 30);
                dispatch(authenticatationSucceeded(json))
            })
    }
}

authenticateUser.reducer.js

import {AUTHENTICATE_USER, AUTHENTICATATION_SUCCEEDED} from "../actions/authenticateUser";

const initialState = {
    calpersIds: [
        5600493427,
        6474994805,
        6452522440,
        5564535492,
        6632408185,
        4618604679,
        5826752269,
        3996179678,
        7302651964,
        1677401305,
        6827859055,
        3685610572,
        6581985123,
        3148148090
    ],
    guidMap: {
        7103503579: "dad08fde-0ac1-404a-ba8a-cc7c76d5810f",
        6632408185: "6632408185-guid",
        6581985123: "6581985123-guid",
        1226290314: "a3908aa7-c142-4752-85ea-3741cf28f75e",
        4618604679: "4618604679-guid",
        6452522440: "6452522440-guid",
        3685610572: "3685610572-guid",
        5564535492: "5564535492-guid",
        5600493427: "5600493427-guid",
        3996179678: "3996179678-guid",
        7302651964: "7302651964-guid",
        3148148090: "3148148090-guid",
        5826752269: "5826752269-guid",
        6827859055: "6827859055-guid",
        1677401305: "1677401305-guid",
        2640602392: "dbed1af6-0fc9-45dc-96a3-ab15aa05a7a2",
        6474994805: "6474994805-guid"
    },
    authToken: null,
    isAuthenticated: false
};
//@TODO: All fetches, create a seperate reducer for store?
export function authenticateUser(state = initialState, action) {
    switch(action.type) {
        case AUTHENTICATE_USER:
            return Object.assign({}, state, {
                authToken: action.token,
            })
        case AUTHENTICATATION_SUCCEEDED:
            return Object.assign({}, state, {
                authToken: action.payload.guid,
                isAuthenticated: true,
                payload: action.payload
            })
        default:
            return state;
    }
};

2 个答案:

答案 0 :(得分:1)

你不应该像你一样使用connect mapDispatchToProps。 该回调应该创建或使用将分派动作的函数。

对于您的情况,您可以像这样使用它:

const mapDispatchToProps = (dispatch) => {
    return {
        authenticate: calpersId => authenticateUser(calpersId)(dispatch)
    }
}

在你的组件中有一个处理提交的函数/方法:

class Login extends Component {
  ...
  handleSubmit = e => {
    e.preventDefault();
    const calpersId = parseInt(e.target[0].value || e.target[1].value, 10) || 0;
    this.props.authenticate(calpersId)
  }
  ...

顺便说一下,reducer应该代表一个实体的状态。名为autenticateUser的实体非常具有暧昧性。您应该将其命名为user。您应该阅读更多的redux示例,以真正捕捉到最初有点复杂的概念。 Youtube上有好的视频。

答案 1 :(得分:0)

原来我正在调用一个不存在的动作创建者,我只需要将我的调度传递给处理程序,然后让它处理事件。

Login.js

import CONFIG from "../../../config";

import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import {authenticateUser} from "../../../actions/authenticateUser";

import Login from '../../../components/views/login/Login'

function handleSubmit(e, dispatch) {
    e.preventDefault();
    let calpersId = parseInt(e.target[0].value || e.target[1].value, 10) || 0;
    dispatch(authenticateUser(calpersId))
}

const mapStateToProps = (state) => {
    return {
        authentication: state.authentication
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        handleSubmit: (e) => {handleSubmit(e, dispatch)}
    }
}

const LoginContainer = connect(mapStateToProps, mapDispatchToProps)(Login);

export default LoginContainer;

这样做的正确方法是什么,我使用了生成相同结果的bindActionCreators。