DRY out React Code into Presentational Components

Roberto Antelo
Yals
Published in
4 min readJun 15, 2017

Don’t Repeat Yourself (DRY) is a programming principle which states that every logic or piece of knowledge in your code should be represented by only one abstraction. With that in mind, changing a given element should not affect the unrelated parts of the application. DRY is one of the key factors to scalability.

React’s approach to building applications encourages developers to build reusable components and modular User Interfaces.

But how can we create efficient reusable components? One way might be to think about our views as multiple blocks that we should be able to move around without any problems. These blocks should not depend on each other and most importantly, they should be able to behave the same way even if we change the data source. A list should render all its elements, regardless of what those elements represent.

A lot of thought has been put into this and the community came out with Container and Presentational Components, which is a way of separating the logic of the application from the presentation. Container Components take care of how the application works, while Presentational Components manage of how it looks. The latter one needs to be simple, general and reusable. If you are not familiar with this concept (also called Smart and Dumb Components), I suggest you read Dan Abramov’s article on this subject.

Let’s get our hands dirty

…and see the entire development flow of a real life Component.

While building yals.mx, in addition to having regular email signup, we needed to have super quick signup via social media. We decided to go with Facebook login first. The requirement was to create a blue button that redirects users to our login endpoint. As simple as this:

<a class='facebook-button' href='/auth/facebook'>Login with FB</a>

Then we needed the next button, this time a red one for Google login.

<a class='google-button' href='/auth/google'>Login with G+</a>

Notice that the structure of the button is the same. That kind of hints us to generalize it, but since we are only using these in a single place there are not enough reasons to put them into a Component yet.

Refactor 1

Moving on, imagine that we also need to add the social media logo to the button and now we are requested to add those buttons to two other views in the app. It’s time to make it portable!

Let’s create a Component that takes two strings, one for the social media type and another one for the text that will be displayed in the button.

At this point, our Component will work as expected. It only needs a defined type and the label to render the button.

Refactor 2

Certainly, there are areas for improvement in this Component. We shouldn’t expect the user of this Component to know what types of Social Media are allowed, nor which strings are allowed. If the user sends ‘Facebook’ as type (note the capital F), the component will render the email login image.
To remove this potential bug, we can add one source of truth: an enumerable containing the exact types that our button allows.

Notice that every time render() is called within <SocialMediaLogin />, it will require the needed image. If, for any reason, the Component re-renders several times, the image will be required again and again. Since we are building a Presentational Component here, we need to be careful not to leave any logic to <SocialMediaLogin />. So, instead of having the Component decide which logo should be printed, the Container that makes the call should take that responsibility.

Final Refactor

With this, we can call our <SocialMediaLogin /> Component without fear of unexpected results. At this point, <SocialMediaLogin/> doesn’t have a state to maintain and it doesn’t make use of any of React’s Lifecycle methods either. This is the perfect situation to transform it into a Functional Component.

Even though the changes don’t look that extensive, Functional Components are a great opportunity to help React optimize our code. They come without State Management and React’s Lifecycle. In React 0.14 release notes, Ben Alpert is optimistic that future releases will avoid unnecessary checks and memory allocations. Plus, Functional Components force you to think in terms of Components at their purest form — as real Presentational Components.

Conclusion

Of course, the creation of several Presentational Components requires that the team interacting with them share a common knowledge. There is no use in having super modular views when people contributing to the project don’t know about the different modules and create ones of their own. With clear communication and a well organized project, this should not be a problem.

DRY principle is a technique capable to leveraging the scalability of your project by creating simple and reusable abstractions. In terms of React, Presentational Components let us apply this principle at its best and provide perks such as pieces of code that are easier to understand, easier to test and completely portable.

--

--