React sub-components

Making flexible, easily testable and reusable views in React without ending in “markup hell”

Maxime Heckel
Feb 26, 2018 · 4 min read
Image for post
Image for post

A more accessible, readable, mobile-friendly and up to date version of this story is available on my personal blog!

This is the first article in a 3 part series about React Sub-components. Part 2 and Part 3 are available here and here.

Every React project I’ve worked on, whether it was personal or work related, got big enough at some point that their codebase became hard to understand. Every little change required more thinking but lead to a lot of inconsistencies and hacks. Among the many issues I had with such codebases, the lack of reusability of some views was the main one: it lead to a lot of copying/pasting code of complex components/views to ensure they look the same, and the resulting duplicated code didn’t make it easier to maintain nor to test.
Using a sub-component pattern can help to fix all these issues.

What exactly is a sub-component?

By using sub-components we can render the same exact view, but with a much more readable code and a reusable component. This is what the result can look like:

In this context, sub-components are defined as components which have their own definition declared within another parent component, and can only be used in the context of that parent component. In the example above, the Title component for instance only exists within the scope of the Article component. It can’t be rendered on its own.
I’m personally not sure about the name, but this is the best term I’ve found to refer to this pattern that I’ve learned to appreciate in my projects.
Sub-components can be seen in multiple libraries such as Recharts or Semantic-UI. The latter refers to sub-components as Modules, Collections and Views in its library, and gives you the ability to render views the same way as stated above.
This kind of pattern is really beneficial:

- to keep views consistent: you can actually show any kind of data using the Article component above. What matters here is that regardless of its purpose, it will look the same across the whole app.
- to keep your code tight and clean: Title, Comments, Subtitle, Metadata only make sense within Article and will only be able to be used within it (i.e. where they make sense, since these components are only used in the context of an “Article”).
- to have easily testable views: for testing such components, Jest and snapshot testing are our allies. It gives us the ability to quickly test any combination of sub-components when using Article. We’ll see how to use Jest to test such a pattern later.

How to build sub-components

  • children: the list of children of Article
  • component: the component we want to find within the list of children, in our example it will be Title.

Here’s how the util findByType looks like:

Now that we have our findByType util, we can start writing our Article component and the Title sub-component:

We now have the ability to use the Article component and its Title sub-component as such:

In order to extend our set of sub-components, we simply need to instantiate each one of them, write their corresponding render function, and call it in the main render function.
Below you will find the fully implemented component with all its sub-components:

Note: the renderMetadata function is really interesting in this example, it shows how it is possible to use a single render function for two different sub-components.

Using Jest and snapshot testing to test sub-components

One last note

What happened? The culprit here was found when debugging the findByType util. child.type.displayName || was returning undefined on IE and Edge for the following reason: “type here is a reference to the component constructor. So if you do, it references the name property on the constructor -- no supported in IE.


As a workaround I added a static variable called displayName for each one of my sub-components to ensure that they have a name. Here’s how it should look like on our example:

If you liked this article don’t forget to hit the “clap” button and if you have any other questions I’m always reachable on Twitter, or on my website. You can also subscribe to my Medium publication to not miss my next post.

Maxime Heckel

Software engineer and space enthusiast.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store