Redux reducer 向数组添加新对象

Redux reducer add new object to array

我在提交后通过调度操作将新对象添加到对象数组时遇到问题。这样做的目的是跨站点显示 flash 消息。我有两个组件负责显示消息,FlashMessagesList 和 FlashMessage。服务器还响应消息对象,需要将其添加到消息数组中。问题是当动作被分派时,我可以看到它是在 redux devtools 中分派的,但是状态从来没有改变过我所做的任何事情,它仍然是空数组,我很坚持这一点,所以欢迎任何建议。这是相关代码:

/* flashMessagesList 组件 */

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import FlashMessage from './FlashMessage';
import { deleteFlashMessage } from '../../actions/actionFlashMessage';

class FlashMessagesList extends Component { //this is conected component cause we need data from store
  render() {
    const messages = this.props.messages.map(message =>
    <FlashMessage key={message.id} message={message} deleteFlashMessage={this.props.deleteFlashMessage}/>
  );
  return (
    <div>{messages}</div>
    );
  }
}
function mapStateToProps(state) {
  return { //here we take a slice of global state
    messages: state.flash.messages //define this in root reducer
  };
}
function mapDispatchToProps(dispatch) {
  return {
    deleteFlashMessage: () => dispatch(deleteFlashMessage())
  };
}
FlashMessagesList.propTypes = { //what this component will take
  messages: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.string.isRequired,
      style: PropTypes.string.isRequired,
      text: PropTypes.string.isRequired
    })
  ),
  deleteFlashMessage: PropTypes.func.isRequired
};
export default connect(mapStateToProps, mapDispatchToProps)(FlashMessagesList); //pass message from store to this component

/* flashMessage 组件 */

import React, { Component, PropTypes } from 'react';
import classnames from 'classnames';

class FlashMessage extends Component {

  deleteFlashMessage = () =>{
    this.props.deleteFlashMessage(this.props.message.id); //dispatch some action that it has on it props
  }
  render() {
    const { id, style, text } = this.props.message; //we can deconstruct message cause it is object
    return (
    <div className={classnames('alert', {
      'alert-success': style === 'success',
      'alert-danger': style === 'danger'
    })}
    >
    { text }
    <button className="close" onClick={this.deleteFlashMessage}><span>&times;</span></button>
    </div>
    );
  }
}
FlashMessage.propTypes = {
  message: PropTypes.object.isRequired,
  deleteFlashMessage: PropTypes.func.isRequired
};
export default FlashMessage;

/* reducerFlashMessage */

import * as types from '../actions/actionTypes';
import deepFreeze from 'deep-freeze';
import expect from 'expect';

const INITIAL_STATE = {
    messages: []
};
const reducerFlashMessage = (state = INITIAL_STATE, action) => {
    switch (action.types) {
        case types.ADD_FLASH_MESSAGE:
            return { ...state,
                messages: [ ...state.messages, {
                    id: action.message.id,
                    style: action.message.style,
                    text: action.message.text
                }]
            };
    }
    return state;
};

export default reducerFlashMessage;

/* actionflashMessage */

import * as types from './actionTypes';

export function addFlashMessage(message) {
      return {
        type: types.ADD_FLASH_MESSAGE,
        message

      };
    }

/* registerUser-我发送 addFlashMessage 的地方 */

export function registerUser({
  timezone,
  name,
  email,
  password,
  passwordConfirmation
}) {
  return dispatch => {
    dispatch(isLoading(true));
    axios.post('/auth/signup', {
      timezone,
      name,
      email,
      password,
      passwordConfirmation
    })
    .then(response => {
      dispatch(_registerUserSuccess(response.data.errors, response.data.message));
      dispatch(isLoading(false));
      dispatch(addFlashMessage(response.data.message));
      dispatch(formReset());
      // browserHistory.push('/signin');
      setTimeout(() => {
              // dispatch(_hideNotifications());
      }, 2000);
      // document.getElementById('form').reset();
    })
    .catch(error => {
      if (error.response) {
        dispatch(registerUserFailure(error.response.data.errors, error.response.data.message));
        dispatch(isLoading(false));
        dispatch(addFlashMessage(error.response.data.message));
      }
      else {
        // Something happened in setting up the request that triggered an Error
        console.log(error.message);
      }
    });
  };
}

/* validation.js 来自我创建消息对象的服务器*/

export function validateSignupForm(payload) {
    const errors = {};
    const message = {};
    if(validator.isEmpty(payload.name)) {
      errors.name = 'Name is required';
    }
    if(validator.isEmpty(payload.email)) {
      errors.email = 'Email is required';
    }
    if(validator.isEmpty(payload.password)) {
      errors.password = 'Password is required';
    }
    if(validator.isEmpty(payload.passwordConfirmation)) {
      errors.passwordConfirmation = 'Password confirmation is required';
    }
    if(validator.isEmpty(payload.timezone)) {
      errors.timezone = 'Timezone is required';
    }
    if (payload.email &&  !validator.isEmail(payload.email)) {
        errors.email = 'Please provide a correct email address.';
    }
    if (payload.password && payload.password.length < 4) {
        errors.password = 'Password must have at least 4 characters.';
    }
    if (payload.passwordConfirmation && !validator.equals(payload.password, payload.passwordConfirmation)) {
        errors.password = 'Passwords must match.';
    }
    if (!isEmpty(errors)) {
      message.id = shortid.generate(),
      message.style = 'danger';
      message.text = 'Check the form for errors.';
    }

    return {
        success: isEmpty(errors),
        message,
        errors
    };
}

你的减速器有错字。而不是

switch (action.types) {

应该阅读

switch (action.type) {