Sitemap
The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +772K followers.

Decoupling Logic From React Components

4 min readNov 15, 2020

--

React / React Native techniques to have smaller components

Have you ever had trouble with big components that have too many responsibilities? Well, so did I. That's why I'm sharing what I have learned with my experience.

There are 6 ways (explored in this article) to achieve the decoupling. Each of them have their pros and cons. And we should not try to apply one technique for all scenarios.

  1. Classes
  2. Container Components
  3. Hight Order Components
  4. Redux + Middlewares (Context API is also a good choice for small projects/functions)
  5. Custom Hooks
  6. Render Props

Study case

Imagine we have a software that have only one page for a restaurant. This page should be responsible for Listing and Filter available meals.

The wireframe given to us was that one bellow, it is a list of meals showing a image, a title and a price of a meal:

Basic Listing page with search feature

Lets keep it simple, abstract that use case for a more complex and bigger example, and you will see it the benefits for using one of the strategies.

The "okay" component

The problems with this component is:

Too many responsibilities: the component is responsible for making API calls, having the logic to show Load indicator, filter the result and, of course, to show the data to the user.

API calls in the component: Generaly that is a bad practice, but it is not the end of the world, we should just be carefull if that api call is reused somewhere else to not repeat code (DRY).

Classes

That aproach can be used to extract API calls, and business logic for domain Models. If we had a bigger app that reused those logics used in this component, we would see a higher impact using classes, but since our case is very basic. We can extract 2 things with classes in this component, API calls and Filter logic.

Result

Things will get more interesting now, all techniques ahead can decouple logic and functions from our "Restaurant" component.

Container Components

This time we will split the code for: "getMeals", "filterMeals" and "load status". In this case we would use MealContainer to be the entry component for our app because "Restaurant" will receive all actions and data from props now.

Result

High Order Component

One thing I didn't see when I first studied HOCs can be used for more things than just to increment New functionalities for other components. With HOCs you can actually separate responsibilities too.

Result

In this scenario our "Restaurant" component became the entry of our app.

Now you are probably thinking "okay, but you basically changed the name of MealsContainer to withMealsController and created a HOC for LoadIndicator!"… Exactly! but we have more flexibility with this pattern, we can create components that will show our load indicator, and the biggest gain is: being able to reuse the "MealsController" for other components totally decoupled from our child component!

Redux + Middlewares

To understand this section I assumed you know how to used Redux + Saga. If you don't want check out their documantation think redux as a state manager and saga a middleware that helps us to create async actions within redux.

Using these libraries we have in this case, the same benefits from using HOCs but using them enables us to "connect" or "subscribe" to state or actions with any component we want, making the components that connect to Redux see only what they need and reuse their functions easily.

Custom Hooks

Result

Conclusion

Our benchmark is the “okay” component snippet, that has 50 lines of code and 0 reusability. Note that theses techniques are not excludent, I gradually maintained some of the patterns as the examples advanced.
Also, consider that this conclusion is not a rule of thumb to apply in any project. Always remeber that any choice comes with a trade-off, just learn the concepts and decide when and which we should apply.

Classes

Pros:

  • reduced 10% lines of code
  • encapsulated logic for API calls and list Filter's logic

Cons:

  • The component still have a lot of responsibilities
  • Low reusability

Container Components

Pros:

  • "Restaurant" turned into a Presentational Component. That means we can change the way our UI look without caring too much about breaking "controller" logic from Container component
  • Separeted concerns for "Restaurant" to focus only on showing data.

Cons:

  • Gained 16% lines of code
  • Can only be used with "Restaurant" component

Hight Order Components

Pros:

  • Same Pros from "Container Components"
  • Can be reused with any component!
  • "Restaurant" component became more readable

Cons:

  • Gained 28% lines of code

Redux + Middlewares

Pros:

  • Same Pros from “Hight Order Components"
  • Redux enables components to subscribe to only what we need, so we have another benefit that wasn't really explored in this example due to the simplicity.

Cons:

  • Gained 300% lines of code (This increase of lines of code is scary, but all the boilerplate results in some good trade-offs, explore that in their doc).

Bonus: Try to make the redux aproach but using MobX or Recoil(experimental by the date of this article). The result is quite interesting.

Custom Hooks

Pros:

  • Same Pros from “Hight Order Components”
  • Better choice because React is highly adopting this pattern, since it is better than using class components.

Cons:

  • Gained 34% lines of code

Thanks for reading all the way here, any suggestions and critics are welcome :)

--

--

The Startup
The Startup

Published in The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +772K followers.

Daniel Kiesshau
Daniel Kiesshau

Written by Daniel Kiesshau

Javascript Developer, enthusiast of investments and entrepreneurship

Responses (3)