TypeError:dispatch不是函数。在React无状态组件中

时间:2017-10-06 11:23:51

标签: reactjs react-redux

我刚刚进入React-Redux。我使用mapDispatchToPropsmapStateToProps成功将几个组件连接到商店,因此我的设置似乎是正确的。现在我有一个带有按钮的无状态组件,该按钮应该发送一个动作:

import React from 'react';
import RaisedButton from 'material-ui/RaisedButton';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { toggleSnackbar } from '../../store/actions';

const handleClick = props => {
    console.log(props.toggleSnackbar)
    props.toggleSnackbar("test")
}

const ButtonComponent = props =>
    (
      <div>
          <RaisedButton
            onClick={() => handleClick(props)}
          />
        </div>
      </div>
    );

const mapDispatchToProps = dispatch => bindActionCreators({
    toggleSnackbar,
}, dispatch);

export default connect(mapDispatchToProps)(muiThemeable()(ButtonComponent))

现在我收到错误:

Uncaught TypeError: dispatch is not a function
    at Object.toggleSnackbar (bindActionCreators.js:3)
    at handleClick (BottomCTA.jsx:28)
    at Object.onClick (BottomCTA.jsx:61)
    at EnhancedButton._this.handleClick (EnhancedButton.js:144)
    at Object../node_modules/react-dom/lib/ReactErrorUtils.js.ReactErrorUtils.invokeGuardedCallback (ReactErrorUtils.js:69)
    at executeDispatch (EventPluginUtils.js:85)
    at Object.executeDispatchesInOrder (EventPluginUtils.js:108)
    at executeDispatchesAndRelease (EventPluginHub.js:43)
    at executeDispatchesAndReleaseTopLevel (EventPluginHub.js:54)
    at Array.forEach (<anonymous>)
    at forEachAccumulated (forEachAccumulated.js:24)
    at Object.processEventQueue (EventPluginHub.js:254)
    at runEventQueueInBatch (ReactEventEmitterMixin.js:17)
    at Object.handleTopLevel [as _handleTopLevel] (ReactEventEmitterMixin.js:27)
    at handleTopLevelImpl (ReactEventListener.js:72)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:143)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.batchedUpdates (ReactUpdates.js:97)
    at dispatchEvent (ReactEventListener.js:147)

控制台记录:

ƒ () {
    return dispatch(actionCreator.apply(undefined, arguments));
  }

toggleSnackbar操作:

export function toggleSnackbar(message) {
  return {
    type: 'TOGGLE_SNACKBAR',
    payload: message,
  };
}

我无法弄清楚这里有什么问题?

编辑:

这是同一个项目中的另一个组件,可以使用相同的aciton工作正常:

import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { bindActionCreators } from 'redux';
import RaisedButton from 'material-ui/RaisedButton';
import './BuyingFormContainer.css';
import { formatDollarToFloat } from '../../shared/formater';
import { BuyingForm } from '../';
import { buyTicket, toggleSnackbar } from '../../store/actions';
import { contentEn } from '../../assets';

const customButton = {
  buttonStyle: { borderRadius: '100px', height: '40px', lineHeight: '35px' },
  overlayStyle: { borderRadius: '100px' },
  style: { borderRadius: '100px', minWidth: '200px', color: '#fffff' },
};

const handleClick = (props) => {
    console.log(props.toggleSnackbar)
  props.buyTicket(formatDollarToFloat(props.buyingForm.values.buyingFormInput));
  //TODO: Trigger this after BUY_TICKET_SUCCESS
  props.toggleSnackbar("Prediction Recieved " + props.buyingForm.values.buyingFormInput)
}

const buyingFormContainer = props => (
  <div className="buyingForm__container" id={'buyingForm'}>
    <BuyingForm />
    <RaisedButton
      label={contentEn.topComponent.buttonLabel}
      style={customButton.style}
      buttonStyle={customButton.buttonStyle}
      overlayStyle={customButton.overlayStyle}
      className="buyingForm_raisedButton"
      secondary
      onClick={() => handleClick(props)}
    />
  </div>
);

buyingFormContainer.propTypes = {
  buyTicket: PropTypes.func.isRequired,
};

const mapStateToProps = state => ({
  buyingForm: state.form.buyingForm,
});

const mapDispatchToProps = dispatch => bindActionCreators({
  buyTicket,
  toggleSnackbar,
}, dispatch);

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

2 个答案:

答案 0 :(得分:5)

connect with an arity of 1使用的唯一参数为mapStateToProps,而非mapDispatchToProps

function mapStateToProps(state) {
  return { todos: state.todos }
}

export default connect(mapStateToProps)(TodoApp)

尝试传递null作为第一个参数:

export default connect(null, mapDispatchToProps)(...)

答案 1 :(得分:0)

尝试toggleSnackbar行动

中的内容
export function toggleSnackbar(message) {
    return (dispatch) => {
        dispatch({
          type: 'TOGGLE_SNACKBAR',
          payload: message
        });
    }
}

通常你不需要bindActionCreators通常返回一个对象就足够了,试试如下:

const mapDispatchToProps = { toggleSnackbar };

并将muiThemeable()放在connect之前作为

export default muiThemeable()(connect(null, mapDispatchToProps)(ButtonComponent))