Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
    );
  }
}
like image 825
MChan Avatar asked Jul 02 '17 11:07

MChan


People also ask

Can we use mapDispatchToProps in functional component?

Yes. You can skip the first parameter by passing undefined or null . Your component will not subscribe to the store, and will still receive the dispatch props defined by mapDispatchToProps .

How do you dispatch actions in a functional component?

There are two ways to dispatch actions from functional components: Using mapDispatachToProps function with connect higher order component, same as in class based components. Using useDispatch hook provided by react-redux . If you want to use this hook, then you need to import it from the react-redux package.

When mapDispatchToProps is called?

mapStateToProps receives the state and props and allows you to extract props from the state to pass to the component. mapDispatchToProps receives dispatch and props and is meant for you to bind action creators to dispatch so when you execute the resulting function the action gets dispatched.

Is it possible to dispatch an action without using mapDispatchToProps?

Without mapDispatchToPropsNotice that the component receives a dispatch prop, which comes from connect() , and then has to use it directly to trigger the actions.


2 Answers

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 !

like image 127
Ravindra Ranwala Avatar answered Nov 15 '22 08:11

Ravindra Ranwala


react-redux provides react bindings for redux. You don't have to use it in order to use redux but it makes all the binding and optimizations under the hood for you.

Instead of manually

  • dispatching your action
  • listening to the store
  • update the state when the store changes

You just connect your component to the redux store with connect() and you're done. connect() will give you back a component where all the dispatch and state values you need will be accessible in the components's props.

like image 23
flocks Avatar answered Nov 15 '22 06:11

flocks