Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind action parameters in mapDispatchToProps

I have a submit button that will dispatch an action. The action's payload is the post data that will be sent to an API. Currently I use bindActionCreators in mapDispatchToProps:

const mapDispatchToProps = (dispatch) => ({
    actions:  bindActionCreators(FormActions, dispatch)
});

then in my component I bind onClick to the submit action:

<input type="submit" onClick={() => this.props.actions.submit(this.props.postData)} />

I don't like that I have to give this component the post data in mapStateToProps. I'd prefer to just give the component an action that already has the post data binded to the submit function so it's usage would look like this:

<input type="submit" onClick={this.props.submit} />

Is this possible? I don't have access to the state in mapDispatchToProps

like image 736
Dave Avatar asked Apr 07 '17 18:04

Dave


People also ask

What are the two parameters of bindActionCreators?

bindActionCreators accepts two parameters: A function (an action creator) or an object (each field an action creator) dispatch.

What is the difference between mapStateToProps () and mapDispatchToProps ()?

mapStateToProps() is a function used to provide the store data to your component. On the other hand, mapDispatchToProps() is used to provide the action creators as props to your component.

Can we dispatch actions from reducers?

Dispatching an action within a reducer is an anti-pattern. Your reducer should be without side effects, simply digesting the action payload and returning a new state object. Adding listeners and dispatching actions within the reducer can lead to chained actions and other side effects.


1 Answers

There is a third argument called mergeProps in connect method of react-redux which is supposed to be used in cases like one you just described. In your case you can do something like:

const mapStateToProps = state => ({ postData: ... });

const mapDispatchToProps = (dispatch) => ({
  actions:  bindActionCreators(FormActions, dispatch)
});

const mergeProps = (stateProps, dispatchProps) => ({
  submit: () => dispatchProps.actions.submit(stateProps.postData),
});

const ConnectedComponent = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Component);

Note that Component will not receive actions nor postData, just submit.

like image 74
fkulikov Avatar answered Oct 23 '22 03:10

fkulikov