One Task, One Component: Moving Beyond the ‘One-Ring’ Approach
A typical situation when we want to reuse as much as possible:`
This tale is as old as React itself, starting with the addition of a simple component. Then, we encounter a nearly identical scenario — just add an icon they said, it’s just on more prop/if. It’s never just one if. Eventually, we end up with a component bloated with 15 props to accommodate all our use cases.
The real challenge begins: every time we edit this component, we risk breaking it across all instances, unless we have tests that covers our back. But we know that’s that’s not the case — cause we didn’t have time to add those.
Soon, this component becomes a gray area, where developers lose confidence and fear making changes.
You probably also have such zones/areas in your project.
Are you ready to take the ‘red pill’ and liberate yourself from this nightmare?
We can tackle the simplest scenario and craft a component that embodies the recipe for that specific case. Let’s call it Dropdown (the name can differ, Generic, Base, UI, etc.). All it does is to receive a list and use 3rd party lib, apply some styles — nothing fancy.
Next, we conduct research to identify the next “victim”. The subsequent use case/recipe involves needing an icon before the text. The solution is straightforward: clone the Dropdown into, for example, RichDropdown — a distinct component/recipe — to implement this scenario, retrieve an icon list, and select an icon based on the option’s value:
Again, picking the weakest “link” from all scenarios that our “Evil” dropdown — that does not “rule them all” anymore, and extract into a bit more complicated dropdown, GroupedDropdown:
Ultimately, when there are no more use cases for the DropdownComponent, we can metaphorically throw it “into the mouth of Mount Doom”.
The End.
In summary:
We’ve distilled specific use cases into dedicated ‘dumb’ components (recipes), removing the fear of implementing new scenarios. Once a scenario is changed, we update the component’s look/behaviour — and not worry about screwing up the other use cases. The paramount advantage? We’ve dismantled the very thing that once haunted our dreams.