Почему mapStateToProps не обновляет реквизиты моего компонента? - PullRequest
0 голосов
/ 17 мая 2018

Я изучаю React и Redux, и я подключил простое приложение, но когда я пытаюсь войти в него, я обнаруживаю, что моя функция mapStateToProps работает не так, как ожидалось. Каждый раз, когда я нажимаю кнопку Submit, получаемый реквизит в итоге выводит список username, password и loggedIn как undefined (сам props не является undefined), хотя правильные значения это хотя бы насколько редуктор. Эти реквизиты остаются неопределенными как до, так и после строки 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 голосов
/ 17 мая 2018

Используя 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} />
...