为什么mapnStateToProps没有更新我的组件的道具?

时间:2018-05-16 23:43:50

标签: reactjs redux react-redux

我正在学习React和Redux,我已经连接了一个简单的应用程序,但当我尝试登录时,对此,我发现我的mapStateToProps功能并未按预期工作。每当我点击Submit按钮时,生成的道具最终会将usernamepasswordloggedIn列为undefinedprops本身就是不是undefined),虽然正确的值使它至少与reducer一样。这些道具在props.history.push("/home")行之前和之后都未定义。在初始页面加载时,道具被正确初始化为initialState。相关部分:

登录组件:

import React from 'react'

const Login = (props) => {
    let user, pass
    const login = () => {
        props.login(user.value, pass.value)
        console.log(props)
        props.history.push("/home")
    }
    return(
      <div>
        <h1>Login</h1>
        <form onSubmit={login}>
          <label> Username:
            <input type="text" className="form-control col-md-12" ref = {node => user = node}/>
          </label>
          <label> Password:
            <input type="password" className="form-control col-md-12" ref = {node => pass = node}/>
          </label>
          <br />
          <input type="submit" value="Submit" />  
        </form>
      </div>
    )
  }

export default Login

登录容器组件:

import { connect } from 'react-redux';
import { logIn } from '../redux/actionCreators';
import Login from './views/Login';

const mapStateToProps = state => {
    return {
        username: state.username,
        password: state.password,
        loggedIn: state.loggedIn
    }
}

const mapDispatchToProps = dispatch => {
    return {
        login: (user, pass) => dispatch(logIn(user, pass))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Login)

动作创作者:

import * as types from './types'

export const logIn = (username, password) => {
    return {
        type: types.LOG_IN,
        username: username,
        password: password,
        loggedIn: true
    }

}
//I have more action creators below

减速机:

import * as types from './../types'

export const initialState = {
   username: "initUser",
   password: null,
   loggedIn: false
}

export const loginReducer = (state = initialState, action) => {
    switch (action.type) {
        case types.LOG_IN:
            return {
                ...state,
                username: action.username,
                password: action.password,
                loggedIn: true
            }

        // More Cases (LOG_OUT)...

        default:
            return state
    }
}

export default loginReducer

商店配置(在根组件中调用):

import {createStore, combineReducers} from 'redux'
import {loginReducer, initialState as loginInitState} from './reducers/loginReducer'
import {messageReducer, initialState as messageInitState} from './reducers/messageReducer'

export const configureStore = () => {
    const store = createStore(
        combineReducers({
            login: loginReducer,
            message: messageReducer
        }),
        {
            login: loginInitState,
            message: messageInitState
        }
    );
    return store
}

export default configureStore

1 个答案:

答案 0 :(得分:0)

使用combineReducers(),您的州最终会看起来像:

{
  login: { },
  message: { }
}

因此,在您的mapStateToProps中,您需要执行以下操作:

const mapStateToProps = ({ login }) => {
    return {
       ...login
    }
};

以上是简写:

const mapStateToProps = state => {
    return {
       username: state.login.username,
       password: state.login.password,
       loggedIn: state.login.loggedIn
    };
};

编辑:更短的版本(归功于@markerikson

const mapStateToProps = ({ login }) => login;

编辑:OP实际上是使用浏览器提交导致页面刷新和消除状态。要修复可以使用preventDefault()

const login = e => {
    e.preventDefault();
    props.login(user.value, pass.value);        
    props.history.push("/home");
};

或者根本不使用提交,只需在常规按钮中执行onClick

<input type="button" value="Submit" onClick={login} />