3 MINUTE READ | July 5, 2017
Common React Mistakes: Monolithic Components and a Lack of Abstraction
Following best practices ensures your application is in the best possible position to live a long healthy life. Some frameworks come with a strong set of opinions that shape best practices. React, however, is very new and very much a library, not a framework. As such, its best practices are still taking shape.
In the past year, PMG has built several single page applications with React and Redux. We’ve learned some of our own best practices through the best (worst) way possible: messing things up.
Monolith components are large components — either class based or functional — that contain a lot of functionality. They’re generally hard to understand and maintain. The goal is to break components like this up into smaller pieces. A lack of abstraction is a similar issue: things that should be broken into pieces are not.
Here are some common code smells and some suggestions for each.
This can originate in the typical control flow structures or because of nested JSX.
For example, a common pattern would be to map across a list and render an element for each item.
A more readable approach would be to pull the row elements into a component.
Say you have some conditional rendering in your component, something simple like:
To really test this in a monolithic component, you have to adjust the props and then fully render to see what actually happens. Extracting that conditional rendering into its own component means you can test it independently. This allows you to do shallow rendering in the bigger component to verify things. Functional components are great for this.
We’re used to extracting common functionality into methods and functions in just about any other language. Duplication in JSX, however, can be a bit more hidden. For example, you may do something like this a lot:
A content + sidebar pattern. Spot the duplication? The magic className values scattered everywhere. Those are prime candidates to pull out into components.
This strategy is a good way to reduce nesting as well.
We’re fans of composition over inheritance in pretty much any programming language. It’s tempting to treat your component’s render method as a template method. Similarly, it’s tempting to use inheritance to provide common functionality to child components.
In both cases, composition is a better approach.
For template method renders, a better approach would be to use specialization of a generic component — see the example above. Providing common functionality is done better with pure functions that can be tested on their own.
Stay in touch
Subscribe to our newsletter
When working with a new library or framework, some trial and error is expected. Code that isn’t easy to read, understand, or test indicates the need for modification. Hopefully, the above suggestions will help you build more sustainable React applications.
2 MINUTES READ | February 4, 2020