MChan MChan - 5 months ago 25
React JSX Question

mapDispatchToProps and directly calling dispatch function in component

While learning about React-Redux I stumbled across the following code where I am not sure what's the difference between the following two lines and using mapDispatchToProps?

let { dispatch, actions } = this.props;
dispatch(actions.createTodo({ todo }));


Can someone please tell me the difference in using the above two lines and using mapDispatchToProps? Also can the above two lines be used in components, containers or only in components? Thanks

import React from 'react';
import ReactDOM from 'react-dom';

export default class TodoForm extends React.Component {
createTodo(e) {
e.preventDefault();

let input = ReactDOM.findDOMNode(this.input);
let todo = input.value;

// ????
let { dispatch, actions } = this.props;
dispatch(actions.createTodo({ todo }));

input.value = '';
}

render() {
return (
<div>
<Form horizontal onSubmit={::this.createTodo}>

</Form>
</div>
);
}
}

Answer Source

You can either use dispatch and not pass mapDispatchToProps, or you can use the props injected by mapDispatchToProps, and not use dispatch. This is why mapDispatchToProps is called this way—it lets you define some other props based on dispatch so you don’t need to use it again.

Here is an example which is using mapDispatchToProps approach. You may find the code here.

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { toggleQuestionModal, toggleConfirmation } from '../actions/questionActions';
import QuestionModal from '../components/questionModal';

class QuestionPage extends Component {
    constructor(props, context) {
        super(props, context);
        this.openModal = this.openModal.bind(this);
        this.closeModal = this.closeModal.bind(this);
        this.afterOpenModal = this.afterOpenModal.bind(this);
    }


    openModal() {
        this.props.toggleQuestionModal(true);
    }

    afterOpenModal() {
        // references are now sync'd and can be accessed. 
        // this.subtitle.style.color = '#f00';
    }

    closeModal() {
        this.props.toggleConfirmation(true);
    }

    render() {
        const { modalIsOpen } = this.props;
        return (
            <div>
                <QuestionModal modalIsOpen={modalIsOpen} openModal={this.openModal} closeModal={this.closeModal} 
                afterOpenModal={this.afterOpenModal} />
            </div>
        );
    }
}

QuestionPage.propTypes = {
    modalIsOpen: PropTypes.bool.isRequired,
    toggleQuestionModal: PropTypes.func.isRequired,
    toggleConfirmation: PropTypes.func.isRequired
};

function mapStateToProps(state, ownProps) {
    return {
        modalIsOpen: state.question.modalIsOpen
    };
}

function mapDispatchToProps(dispatch) {
    return {
        toggleQuestionModal: bindActionCreators(toggleQuestionModal, dispatch),
        toggleConfirmation: bindActionCreators(toggleConfirmation, dispatch)
    };
}

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

This is the recommended approach. When you pass mapDispatchToProps to the connect helper, your action is bound to the props. Hence you can call it using this.props.yourAction.

The other approach is to dispatch the action directly to the store. You can do it like this.

    import {loadCourses} from './actions/courseActions';
    import configureStore from './store/configureStore';

    const store = configureStore();
    store.dispatch(loadCourses());

The configureStore file for a dev environment would be something like this.

import { createStore, applyMiddleware } from 'redux';
import rootReducer from '../reducers';
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
import thunk from 'redux-thunk';

export default function configureStore(initialState) {
  return createStore(
    rootReducer,
    initialState,
    applyMiddleware(thunk, reduxImmutableStateInvariant())
  );
}

Also notice that here I am using redux-thunk middleware. Apart from the above explanation, I would like to recommend you to go through this discussion as well. Hope this helps. happy coding !