Configurable Containers with React

Jacob Kelley
DSC Engineering
Published in
3 min readOct 9, 2018

--

The container pattern is a popular pattern you’ll see here in Dollar Shave Clubs React applications. Containers are responsible for fetching data, dispatching actions, and mapping information to a view component among other things. As our software become more functional, we often look to optimize the ease of development.

1. Add-Ons Page

Let's take a look at a sample container and route that might be used to power a page that allows you to add additional products to your cart:

AddonsContainer: Renders AddonsView, maps state, and supplies an action to add products to the cart
Maps the AddonsContainer to the route “/get-started/add-ons”
The “Addons” page

Here we’ve created a new page whose container imports the AddonsView and maps state & actions to props. Nothing fancy here.

What if we want to test a different view? We have a couple options:

Solution 1: Embed additional logic in the container to determine what view to load. The downside with with this is that the container can get messy, and if you need the new view at a different route, things get more complex.

Solution 2: Duplicate the container entirely and change the one line of code that specified which view to import. The issue with this is unnecessary code duplication. There is a simplicity in doing this but we can do better.

Solution 3: Instead of calling the function returned from connect(...)(AddonsView), simply return it.

2. Extras Page

The “Extras” page has the exact same logic as Add-Ons, but leverages a completely different view.

AddonsContainer no longer calls the function returned from connect
Instead, we call the function within our routes.

All we need to do now is hook up the container with the view directly within our router and voila: multiple views with a single container.

The “Extras” page. Same logic, different UI

3. Upsell Page

What else can we do? Anything, really. It’s just Javascript. Say we not only need to specify a different view, but we want to specify different products to load. Lets modify our new Upsell container to export our own function that takes in an object of options:

This can now be used in a more configurable fashion within our routes:

Summary

Instead of exporting the regular compose or connect, export anything you want! Reacts architecture empowers the language itself, lets take advantage of that.

Some downsides include the following:

  • Feature Creep: Containers get too big when one page needs an additional feature that another page may not. This is a constant balancing act that will live on in any codebase regardless of stack, technology, or engineers.
  • Unconventional: We’re beginning to export things that you wouldn’t expect from container files. This is where solid testing, documentation, and communication becomes more prudent with you and your team.

At the end of the day, you should use what works best for you. Configurable Containers can be a powerful way to create and shape the experiences you want for your customers while keeping that codebase lean.

Want to help shave some code off of our codebase? Hit us up on Twitter or check out our Careers page to explore opportunities!

--

--