React Redux Connectors pattern
Tags: react, redux, javascript
Published: 2019-03-06 21:50:17

---
title: React Redux Connectors pattern
published: true
description: Yet another React's pattern
tags: react, redux, javascript
---

## TL;DR

Don't worry, I'm not here to talk about the umpteenth `react-redux-whatever` package.

This post is rather a moment of reflection on what could be a simple but powerful approach to avoid generating dependencies between what would be called **containers** and what we normally call **components**.

Many of you will have found their way to solve this problem; for those who did not, keep reading.

## The problem

How many times have you found yourself in front of a new project, maybe created using `create-react-app`, armed with good intentions not to repeat the same mistakes that have generated technical debt in previous projects? I already imagine many of us at that precise moment:

_"This time the codebase will be well structured"_, _"The folders will have only one level of subfolders, maybe two"_ or _"I will not bind the components to the containers again"_.

The last famous words.

## The reasoning

When we talk about **containers**, we are defining nothing but components that are enriched with information from a HOC: **connect**.

The problem is not about writing **mapStateToProps**, **mapDispatchToProps** and **mergeProps** (yes, there is a third parameter and it is fantastic) again and again and again. The problem is, rather, to know what to do with these **components** connected to the Redux store.

_"Do I include the presentational logic within them? But if I have to move it or modularize it, I should rewrite everything ..."_

## The naive solution

_"Actually I don't see all this distinction between **components** and **containers** ... Now I will make sure that every component can access the status of Redux when and how it wants, after all we are talking about Context"_.

![](https://media.giphy.com/media/vNp0u58iw8FPn8F1jN/giphy.gif)

## Connectors (?)

For some time I like to ask myself the question _"how would I like to write it/use it ?"_ before implementing any utility in Javascript or React.

In the same way, to solve this problem, I would like to write something like this:

```react
<Layout>
  <Layout.Header>
    <h1>Header</h1>
  </Layout.Header>
  <Layout.Main>
    <PostsConnector>
      {({ posts }) => posts.map(post => (
        <div key={post.id}>
          <h2>{post.title}</h2>
          <p>{post.body}</p>
        </div>
      ))}
    </PostsConnector>
  </Layout.Main>
</Layout>
```

This way of looking at it reminds me a lot of the Javascript closures.

After all, React is a powerful library for the fact of leaving freedom and dynamism to the developer to be able to create as preferred the tree of components, either in JSX or not.

Why, at this point, I can not take advantage of some generic Javascript programming concepts in order to solve this kind of specific problems?

## Connector's creation

```react
// imports

class PostsConnector extends Component {
  componentDidMount() {
    const { fetchOnMount, fetchPosts } = this.props

    if (fetchOnMount) {
      fetchPosts()
    }
  }

  get childrenProps() {
    const { posts, fetchPosts, createPost } = this.props

    return {
      posts,
      fetchPosts,
      createPost,
    }
  }

  render() {
    const { children } = this.props

    return children(this.childrenProps)
  }
}

// PropTypes and connect's logic
```

Or using React Hooks

```react
// imports

const PostsConnector = ({
  children,
  fetchOnMount,
  fetchPosts,
  // Redux
  posts,
  fetchPosts,
  createPost,
}) => {
  useEffect(() => {
    if (fetchOnMount) fetchPosts()
  }, [])
  
  return children({
    posts, fetchPosts, createPost,
  })
}

// PropTypes and connect's logic
```

Done ✅

## Bonus: `composeConnectors`

All this is very nice but .. _"If I had more connectors inside each others?"_.

In this specific case, your problem may be to have too many connectors.

In the case, however, you still want to proceed and try to avoid the connectors-hell and write something like this:

```react
const ComposedConnector = composeConnectors(
  <PostsConnector />,
  <PostConnector postId="super-secret-id" />,
)

<ComposedConnector>
  {props => console.log(props) || null}
</ComposedConnector>
```

You can use this utility function:

```react
import React from 'react'

// return ({ children }) => (
//   React.cloneElement(connectors[1], null, secondProps => (
//     React.cloneElement(connectors[0], null, firstProps => (
//       children({ ...firstProps, ...secondProps })
//     ))
//   ))
// )

const composeConnectors = (...connectors) => (
  connectors.reverse().reduce((composed, connector) => (
    ({ children, ...childrenProps }) => (
      React.cloneElement(
        connector,
        null,
        connectorProps => composed({ ...childrenProps, ...connectorProps, children }),
      )
    )
  ), ({ children, ...props }) => children(props))
)

export default composeConnectors
```

## Thanks for reading

If you liked this article just let me know; if not, let me know it anyway.

![](https://media.giphy.com/media/upg0i1m4DLe5q/giphy.gif)