Technical Blog

Why I'll definitely use mapDispatchToProps in Redux

January 05, 2020 - 4 minutes

Not too uncommon, at my job we make use of Redux in our React frontend stack for state management. A lot of components are connected to the store using Redux’s connect and retrieve data from it through mapStateToProps using selectors. Components also need to interact with the store through actions or thunks, which is possible with the dispatch function that connect injects. With those concepts in mind, I’ve passed along the dispatch function to the component and used it inside its callbacks and lifecycle methods for quite some time now, without ever second guessing this approach. Until recently that is, when I learned about the second argument of the connect function: mapDispatchToProps.

What is mapDispatchToProps?

In short, mapDispatchToProps is a function that maps the dispatch function and returns an object of functions, which will be merged into the existing props and made available to your component as additional ones. It’s very similar to mapStateToProps, which maps the state to props for your component, but then for the dispatch function and the values of the return object have to be functions. If you want to learn more about what mapDispatchToProps is and how to use it, you should read the Redux docs as they explain it in quite some detail.

function mapDispatchToProps(dispatch) {
  return {
    doSomething: () => {
      dispatch(somethingDispatchable());
    },
  };
}

class SomeComponent extends React.Component {
  componentDidMount() {
    // Instead of `this.props.dispatch(somethingDispatchable());`
    this.props.doSomething();
  }
  // or...
  render() {
    const { doSomething, ...otherProps } = this.props;
    return <button onClick={doSomething} />;
  }
}

export const SomeConnectedComponent = connect(null, mapDispatchToProps)(SomeComponent);

Why use mapDispatchToProps?

First of all, it shares a lot of benefits with mapStateToProps, like making your code more declarative and making sure that Redux related code is more grouped together. The latter might not seem so impactful for mapStateToProps, as it’s only responsible for retrieving data from the store. But in the case of mapDispatchToProps, it’s definitely something not to overlook as it’s responsible for defining the logic of the component’s interactions with the store. Logic code has always been difficult to maintain, and keeping related logic together is one way of making this process easier. A concrete example is the introduction of Hooks in React.

It also reduces boilerplate code in your components as less callbacks are required in which dispatch is called and the logic is moved somewhere else. This in turn reduces how bloated your components are, thus resulting into components that are easier to read and maintain. This is especially the case for class components, which are more verbose in general.

However, the main benefit that I see in using mapDispatchToProps is the separation it creates between store related logic and the view of the component and the testing benefits that come with it. Components are not aware anymore of dispatch and thus don’t need to know how things have to be done anymore. Rather, all the logic is abstracted away. Which means that the components only see the resulting props and only need to bother with what they do and when to use them. This significantly increases the reusability and testability of the component.

While it’s up for debate whether components should be tested with or without the store, there are use cases in which you need the unconnected component or where it makes more sense to test the component without an attached store. In those cases, having mapDispatchToProps means you can more properly and easily test the logic. Rather than mocking the dispatch function and then verifying whether it’s called with the appropriate action creator/thunk, in which case you’re actually testing implementation details, you can now mock the logic and inject it directly into the component as dependencies.

// Example of how `mapDispatchToProps` makes testing more straightforward.
test('SomeComponent should do something correctly', () => {
  const mockedDoSomething = jest.fn();
  const component = mount(<SomeComponent doSomething={mockedDoSomething} />);
  // Interact with the component to trigger the callback. In this case it's done on mount,
  // but here you would simulate click events if it's attached to a button for example.
  expect(mockedDoSomething).toHaveBeenCalled();
  // Other verifications.
});

Just like the React community, my testing focus is shifting towards verifying behaviour/interactions of my React code, which I’ve also advocated for to do so at my job. Good practices that allow me to write more proper and meaningful tests in an easier way for my React component have interested me a lot since then. The mapDispatchToProps is a great example of this as it clearly separates Redux related code, the logic, from the React component code, the view. Ultimately, this leads to more reusable and testable components, which is one of the core values of React.

References


After graduation, my career is entirely centered around learning and improving as a developer. I’ve began working full time as a React developer and I’ll be blogging about everything that I encounter and learn during this journey. This will range from improving communicational skills in a technical environment, becoming a better developer, improving technical skills in React and JavaScript, and discussing career related topics. In all of my posts, the focus will be on my personal experiences, learnings, difficulties, solutions (if present), and also flaws.

If you’re either interested in these topics, more personalised technical stories, or the perspective of a learning developer, you can follow me either on Twitter or at Dev to stay up to date with my blogposts. I’m always learning, so stay tuned for more stories! 🎉