2021-09-09
|~3 min read
|446 words
I’ve written in the past about composability and polymorphism in the past and it’s a concept that continues to interest me.
I was speaking with a colleague recently about how we might be able to create more reusable components in React.
Specifically, we wanted to divorce the semantics of the markup (whether the element was a button, an input, or a link) from the appearance of the element. At the same time, we were hunting for solutions that would make the use of these components ergonomic.
Perhaps it will be useful to think about some examples in greater details.
Imagine an app that has the concept of a “card”.
Except card is a suitcase word. Folks pack into whatever they mean. So let’s try to be specific.
In our app, a card lays out information. Sometimes there’s a lot of information in a stack layout. Other times it’s just a single word.
Cards can also be navigable. When they’re clicked, they navigate the user to a new page in the app (and when they do, you want to make sure they take you to the top of the page).
But sometimes they’re not. Sometimes they are used to indicate a selection. When the card is selected, it has a highlighted border.
Cards also have different “flavors”. For simplicity, think of a white card and a red card.
At this point we have:
If we just opened up the API to the component to handle all these cases, we’d have eight possible states. And the number of permutations here is still relatively small! Not only that, but the different behaviors require totally different information.
This leads to a few undesirable possibilities:
Fortunately, we know discriminated unions are quite capable at combatting exploding cardinality. But, how might that work?
My first attempts are documented in this CodeSandbox which is definitely still a work in progress.
Things that I like about this pattern:
Things I don’t love (yet):
Hi there and thanks for reading! My name's Stephen. I live in Chicago with my wife, Kate, and dog, Finn. Want more? See about and get in touch!