When asked to add new functionality to a component, what comes to mind first? Adding more props?
If you were building a component to be reused across multiple applications, would your implementation strategy rely on just taking in more and more props to accommodate the desired use cases?
Even though props are the first introduction you get to React component reusability, exposing your component to more and more props doesn't necessarily translate to more reusability.
Why is relying on more props a problem, and how does this eventually impact component reusability?
In this post, I’ll share with you problems you’re bound to incur if you rely on just passing more props to cater for component reusability. While you may get away with this for really simple components, as you build more complex UI components and want to allow for maximum reusability, you’d have to reconsider your strategy to rely on more trusted component patterns.
Overlooking the big picture
Think for a moment about how most people approach the problem of component reusability.
What typically happens is they get a specification or certain use case to be implemented, and by default they think of passing a new prop to conditionally render some UI or perform a certain operation. Voila! Problem solved.
When you think in this way, you miss the bigger picture.
Building a truly reusable component should go beyond catering to the specific use case at hand. Ideally, you should also consider:
- Extensibility of style and functionality
- Exposing an intuitive API
- Maintainability & Reducing code complexity
Let’s take a look at each of these.
Extensibility: Handling several use cases
Regardless of how careful you are, if you only think about solving the problem at hand or a handling a singular use case, you’d overlook the multiple use cases your component users will eventually throw at you.
What happens is you solve the problem now by passing a few props:
And in the future when there’s a case you forgot to handle, you think again in props and just go ahead to pass in more props:
This is far from ideal.
If you build complex components (and I’ve seen some of those) you’d easily end up having a component with 50+ props.
Something about this, you can tell, doesn’t feel right. Not when there are more intuitive ways to provide component reusability without relying on props overload.
You should think in a way that allows your component take in a few important props that cater to generic use cases and still allow for maximum flexibility.
If you think this way, you’d solve the problem at hand and also allow for extensibility - solving multiple use cases you might not have planned for.
Exposing an Intuitive API
The art of programming in itself embraces trade offs. You usually have to sacrifice something for the other e.g. readability over early-optimisations.
Catering to your component reusability solely via passing more props leads to you knowingly or unknowingly sacrificing the exposure of an intuitive API for what seems like reusability.
If you performed a google search for react modal component (or any other UI component for that matter), you’d find tons of them. While users appreciate extensibility, and making sure their open source component of choice caters to their use case, they also want to be sure you expose an intuitive API.
If they had to compare multiple modal components that cater to their specific use case, a user would choose the easier “modal” to integrate into their app. Exposing an intuitive API is thus an integral part of building reusable components developers like yourself would love to use, and a component with tons of props doesn’t necessarily scream intuitive!
Maintainability & Reducing code complexity
Some of the most popular programming principles include the KISS and SOLID principles.
KISS, Keep it stupid simple, preaches simplicity, and for good reasons! Why introduce 20 props to your component if you could solve the same problem elegantly with fewer props?
I advocate for keeping it simple by leveraging established React component patterns for true reusability.
Of all the SOLID principles, the principle of concern here is the Open-closed principle. In object-oriented programming, the open/closed principle states "software entities should be open for extension, but closed for modification"
Here’s what happens when you rely on more props.
Every time there’s a new use case to be handled, you go ahead to add more props and go modify some part of your UI logic to handle these.
If you treated your component as the software entity described by the principle, it becomes obvious this is arguably a sub-optimal way to go about this.
What if you could have certain specific props that cater to making the entity extensible? Props that rely on trusted patterns for reusability?
This way you’d not have to always modify your component to handle more use-cases, but rely on the user extending your component via established prop patterns.
NB: The use of extension here doesn’t mean extension as in OOP. Your component should remain composable, but extensible in terms of functionality.
Building components with this mindset lets you ditch the reliance on passing more props, and yet have perfectly reusable components.
The Illusion of Reusability
I believe that relying on more props, while they seem to solve the problem at hand and could eventually handle a number of use cases, leads to the illusion of reusability.
You expose a component that seems reusable on the outside, but masks bigger problems underneath.
Problems that’ll hunt you sooner than later as more users adopt your reusable component.
Over the next several days, I’m going to be giving more lessons on the concept of building truly reusable React components, to try to give you the tools you need to build components you’d love building and users would love using by leveraging trusted, proven and battle tested patterns for true reusability.
After, starting on Monday, 17 February, 2020, I’m going to open my new Udemy course, The Complete Guide to Advanced React Patterns! For those who want to go deeper and start the process of mastering the art of building truly reusable components.
See you later!