我刚刚进入React-Redux。我使用mapDispatchToProps
和mapStateToProps
成功将几个组件连接到商店,因此我的设置似乎是正确的。现在我有一个带有按钮的无状态组件,该按钮应该发送一个动作:
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);
答案 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))