MapDispatchToProps and directly call the dispatch function in the component
After learning about React-Redux I came across the following code where I am not sure what is the difference between the 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 these two lines be used in components, containers or just components? Thanks to
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>
);
}
}
source to share
You can use dispatch
or not transfer mapDispatchToProps
, or use the details entered mapDispatchToProps
and not use dispatch
. That's why it's mapDispatchToProps
called this way - it allows you to define some other props based on it dispatch
, so you don't have to use it again.
Here's an example that uses the approach mapDispatchToProps
. You can 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 to a mapDispatchToProps
helper connect
, your action is bound to props. Hence, you can invoke it using this.props.yourAction
.
Another approach is to send 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 the dev environment will look 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 note that I'm using redux-thunk middleware here. Apart from the above explanation, I would like to recommend that you go through this discussion . Hope this helps. happy coding!
source to share
reaction-reduct provides binding reaction for reduction. You don't need to use it to use the shortcut, but it does all the bindings and optimizations under the hood for you.
Instead of manual
- sending your action
- listening shop
- update state when storage changes
You just connect your component to the redux store using connect()
and you're done. connect()
will provide you with a component in which all required dispatch and state parameters will be available in the component props.
source to share
mapDispatchToProps
used to bind your actions to the store. Typically, action creators are completely independent of any store. Thus, the actions can be tested easily.
In Redux, you have one central store that is initialized once in the component lifecycle. react-redux
provides a way to access this store in all components that need to access the store in a higher order component ( connect
). The store has two main functions: getState()
and dispatch(action)
.
- Holds the state of the application;
- Allows access to state through getState ();
- Allows to update the state by submitting (action);
Redux repository documentation
react-redux
connect
the function wraps the component and injects properties into the component. Some of these properties are always inserted and you cannot select them as dispatch. The function also takes two parameters. One of them is well known mapStateToProps
. It is your function of choice to decide which parts of the store you want to receive inside your component as properties. The second parameter can either be an action creator object or a function that receives a dispatch function and also returns an object that is bundled into the properties of your component. This allows components that are unaware of the Redux concept and just take properties.
Redux docs with React and connect docs to react-redux repository
I've created a minimal react-shortcut example at codesandbox.io . Feel free to play with different versions of the action-challenger.
One note on containers and components: I wouldn't bother with best practices until you understand what redux does. This concept is also not that important to Redux.
source to share