A pattern to write clean Redux connected components
Tags: redux, react, ramda, functional
Published: 2019-09-14 02:47:17

---
title: A pattern to write clean Redux connected components
published: true
description: A neatness pattern I developed to write clean mapDispatchToProps functions
tags: Redux, react, ramda, functional
---

Some components have a lot of side-effect functionality going on. Some of my projects use Redux with redux-saga for all side effect management. I came across a lot of code on Redux web apps where the mapDispatchToProps function looked really huge and weird. Moreover, I've seen a lot of people manually call

```javascript
  dispatch(someActionCreator);
```

throughout their components; which is again not a very nice looking thing to do.

I think useSelector and useDispatch are great when your component has only a few selectors and actions used; but otherwise I don't see myself littering the first 20 lines of my React component with useSelectors; and then having to wrap each actionCreator in a dispatch throughout. Here's how I do things:


```javascript
// makeActionCreatorsToBind.js

import { pick } from 'ramda';

export default ({ actionCreators, keysToPick }) => pick(keysToPick, actionCreators);

```


```javascript
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { compose, assoc } from 'ramda';
import { createStructuredSelector } from 'reselect';

import CheckoutPage from 'modules/Checkout/';

import * as checkoutActionCreators from 'modules/Checkout/redux/actions';

import { makeSelectCart } from 'modules/Cart/redux/selectors';

import makeActionCreatorsToBind from './makeActionCreatorsToBind';


function Checkout(props) {
  return (
    <CheckoutPage
      {...props}
    />
  );
}

/* add some other action creators from different modules,
* I'm using Ramda here just so people reading this can
* pick up composition patterns.
*/
const actionCreators = compose(
  assoc('getCreditBalanceRequest', getCreditBalanceRequest),
  assoc('reinitializeCart', reinitializeCart),
))(checkoutActionCreators);


// another way of doing the same thing:
const actionCreatorsMadeWithoutRamda = {
  ...checkoutActionCreators,
  getCreditBalanceRequest,
  reinitializeCart,
};

const actionCreatorsToBind = makeActionCreatorsToBind({
  actionCreators,
  keysToPick: [
    'reinitializeCart',
    'getCreditBalanceRequest',
    'shippingRequest',
    'createOrderRequest',
    'sendOrderDetails',
    'getTotalsRequest',
    'confirmOrderRequest',
    'reinitializeCheckout',
    'applyAddressData',
    'applyCouponCodeRequest',
  ]
});

const mapDispatchToProps = dispatch => bindActionCreators(actionCreatorsToBind, dispatch);

const mapStateToProps = createStructuredSelector({
  cart: makeSelectCart(),
});

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

```


I'll explain bits of the code.

## bindActionCreators

Redux exposes this function, which basically can take an object with key-value pairs, where the values are action creators; and decorate all the action creators with dispatch, so that you can call the keys, i.e. the names of those action creators as if they're normal functions.

## the Ramda bit

### assoc => basically a functional way of doing myObject['propertyName'] = someActionCreator

### compose => starting from the last function, returns a function that applies all the functions right to left (bottom to top) on the provided argument.

The ramda bit basically creates an object `actionCreators` that takes an argument (checkoutActionCreators from a file where action creators are described in this case, and there's like *many* of them), and adds some other action creators from some other files to that object.

The compose function adds keys `reinitializeCart` and `getCreditBalanceRequest` with the values of action creators with the same names; imported from some other module.

We then use this new object to call our makeActionCreatorsToBind function and assign the result to a variable named actionCreatorsToBind. This function takes out just the actions that our component needs and returns an object with our specified keys, ignoring the actions we don't need from checkoutActionCreators.

Now we can pass this new object (named actionCreatorsToBind) to bindActionCreators and voila, everything looks neat and works well.