【问题标题】:Redux state props value is undefinedRedux state props 值未定义
【发布时间】:2018-05-12 19:44:57
【问题描述】:

大家好,所以我正在创建用户登录的模拟。我正在使用 redux 记录器,记录的状态值始终是我想看到的值,但是,当我是 console.log( this.props)

我总是返回未定义。我的减速器有一个我已经定义并作为默认值传入的状态值。我不确定为什么我会返回 undefined 并且无法弄清楚。这是我的代码。任何帮助将不胜感激,我需要访问这些值,但未定义它不起作用。

我将压缩样板文件,如导入语句等。也再次说明上下文。我要做的就是在我的组件内部能够访问在我的减速器内部定义的状态值。例如,其中之一是 isLoginPending。当我在 console.logging this.props.isLoginPending 时,我希望获得默认值或新的 Object.assigned 值而不是未定义。我的理想目标是在我的组件内部获得一个未定义的值。

这是我的组件

render() {
        let {email, password} = this.state;
        console.log("PROPS*****" + this.props.isLoginPending);
        return (
            <div className="form-wrapper" >
                <form onSubmit={this.submit} name="login-form">
                    <label htmlFor="login-form">Email</label>
                    <input onChange={this.changedEmail} type="email" />
                    <br />
                    <label htmlFor="login-form"> Password </label>
                    <input onChange={this.changedPassword} type="password" />
                    <button type="submit">Login </button>

                </form>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.isLoginPending,
       isLoginSuccess: state.isLoginSuccess,
       isloginError: state.isloginError
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        login: (email, password) => dispatch(login(email ,password))
    };
}


export default connect(mapStateToProps, mapDispatchToProps)(LoginForm);

减速器

 export default function (state = {
        isLoginPending: false,
        isLoginSuccess: false,
        isLoginError: null
    }, action)
     {
        switch(action.type) {
            case constants.LOGIN_SUCCESS:
            console.log("state" + state.isLoginPending);
            return Object.assign({}, state, {isLoginSuccess: action.isLoginSuccess})

            case constants.LOGIN_PENDING:
            return Object.assign({}, state, {isLoginPending: action.isLoginPending})

            case constants.LOGIN_ERROR:

            return Object.assign({}, state, {isLoginError: action.isLoginError})

            default: 
            return state
        }
    }

动作

export const login = (email, password) => {
    return dispatch => {
        dispatch(loginPending(true));
        dispatch(loginSuccess(false));
        dispatch(loginError(null));

    sendLoginRequest(email, password, error => {
        dispatch(loginPending(false));
        if(!error) {
            dispatch(loginSuccess(true));
        } else {
            dispatch(loginError(error));
        }
    });
    }
}

const sendLoginRequest = (email, password, callback) => {
    setTimeout(() => {
        if(email === 'admin@admin.com' && password === 'password') {
            return callback(null);
        } 

        else {
            return callback(new Error("invalid email or password"));
        }
    }, 1000)
}

** 编辑 **

const createStoreWithMiddleware = applyMiddleware(thunk, logger)(createStore);

ReactDOM.render(
  <Provider store={createStoreWithMiddleware(reducers)}>
    <App />
  </Provider>

传入 store 的根 reducer

const rootReducer = combineReducers({
  loginForm: emailReducer
});

export default rootReducer;

【问题讨论】:

  • 你的店铺定义在哪里? Provider 长什么样子?
  • 请以最好的方式接受这个,但我绝对确定这与我的商店或我的供应商无关。我的动作和减速器正在连接起来,我只是回到未定义的状态。
  • 我不认为有必要采取防御姿态;)我正在尝试调查您的mapStateToProps 是否真的映射到您似乎期望的正确状态。但是,您的 reducer 返回一个对象,现在如果您使用 combineReducers,那么您将拥有一个基于多个不同键的状态,并且您的 store 可以指示您当时的状态结构是什么
  • 对不起,我并不是要采取防御姿态。我将编辑并发布我的 store 和 combineReducers 方法。
  • 那么随着更新,mapStateToProps 不应该指向state.loginForm.isLoginPending吗?

标签: reactjs redux redux-thunk


【解决方案1】:

问题在于您的 mapStateToProps 对象,即您希望标志处于根状态

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.isLoginPending,
       isLoginSuccess: state.isLoginSuccess,
       isloginError: state.isloginError
    }
}

然而,当我们看到你的根 reducer 时,你有一个多级状态,它在 state.loginForm 中添加了这些标志

const rootReducer = combineReducers({
  loginForm: emailReducer
});

所以应该像这样改变你的 mapStateToProps

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.loginForm.isLoginPending,
       isLoginSuccess: state.loginForm.isLoginSuccess,
       isloginError: state.loginForm.isloginError
    }
}

【讨论】:

  • 对于那些使用 TypeScript 的人:我遇到了同样的问题。我使用子状态作为 mapStateToProps 的方法属性类型,所以智能感知没有提醒我我的错误。即 RootState 由(使用 combineReudcers)SubState1 和 SubState2 组成。对于我的组件,mapStateToProps 最初的方法属性类型为 SubState1,这是不正确的。 RootState 是属性类型。
【解决方案2】:

您通过rootReducerloginForm 作为存储传递给连接的组件:

const rootReducer = combineReducers({
  loginForm: emailReducer
});  

所以在mapstateToProps 里面你可以这样做:

const mapStateToProps = (state) => {
    return {
       isLoginPending: state.loginForm.isLoginPending,
       isLoginSuccess: state.loginForm.isLoginSuccess,
       isloginError: state.loginForm.isloginError
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多