React composable user interface is much like a double edged sword. On one hand you can decompose UI component quite easily, but the decomposing is only applied to the UI; thus suppose there is an atomic UI with complex logic, we can not easily decompose that. To proves my point, I create a simple chat program below. You can access the repo here. Readers are advised to skim through my repo first so you can understand the point of the post better.

Simple chat apps with select and delete functionality

First we are gonna decompose the UI. You should’ve noticed that the chat bubbles are redundant and can be composed into a new component, so we’ll create the component!

Invoking chat balloon in App.js

By creating a component for chat balloon, we can simply invoke the Balloon component while populating the chat list. By decomposing the UI, our apps become loosely coupled and simple enough to develop, or is it?

If we look more closely, the main component is bloated by functions that mainly modify the conversations state.

Unlike UI, we can’t easily decompose class methods. The reason? Well, because React is only the View; thus it can only breakdown the component based on the UI. We can’t move those methods to Balloon component, because it is the main component responsibilities.

Therefore, I propose a pattern for handling huge React component that’s bloated by class method. I use Object Composition Pattern or better known as Composition Over Inheritance.

The main idea is by creating a data class for the sole purpose to maintain and modify a state of a component. This data class will use component state as it class variable. Every modification action will be moved to this class, and will be invoked in the components. The component’s state will be updated corresponding to the data class variable. See below for the simple chat program implementation.

A data class for our main UI component

Smaller file size and manageability are not the only advantage from this pattern. By separating a state to it’s new class, the UI component doesn’t need to know the data logic, only the business logic. Counting selected items, selecting items, etc will be handled by the data class, the UI only need to know what and when to invoke the logic; thus it’ll increase the code readability. It is very important, like Uncle Bob said:

“Indeed, the ratio of time spent reading versus writing is well over 10 to 1. We are constantly reading old code as part of the effort to write new code. …[Therefore,] making it easy to read makes it easier to write.” ― Robert C. Martin

The testability of the apps will become better. We can test the data and UI state separately as their responsibilities are separated as well. It follows the Single Responsibility Principle (SRP) as mentioned before. And the last but not least, it follows the Open/Closed Principle, suppose there’s a new feature that we want to add it, we can simply add a methods in the data class. We don’t need to modify any existed methods as the responsibilities are clear for each methods.

Final Words

Well, this marks the beginning of the end of this post. Once again I’m gonna mention that this is a proposed method, not saying that this is the perfect solution. Many of you maybe will argue that by using flux like library we can solve this kind of a problem, but let me ask you a question. Is it worth the hassle to build reducer, action dispatcher, and all that just for toggling a flag in a list of items? Drop a comment and let me know what’s your opinion on this, I’m always open for discussion :)

That’s it for my first (hopefully it’s not the last) post. Follow me on medium (and twitter of course) so you’ll get notified for my latest post. Bye~