“Two roads diverged in a yellow wood…”
~ Robert Frost
“…I took the codepath the condition was handled by.”
~ Probably Not Robert Frost
Mutual exclusivity is an extremely common logical pattern in programming. Requests can succeed, or they can fail. A user can be logged in, or they can be logged out.
Mutual exclusivity need not be limited to two opposing conditions, either: a user could have a draft of some document that, after submission, is pending review; then, while under review, the document might be marked as claimed by the reviewer until that reviewer marks the document approved or denied. Maybe the document is approved, but is then pending peer- or managerial review. Maybe the document’s approval state is contingent upon additional action on the submitter’s part. Throw in conflict management in maintaining these many states between multiple reviewers and the cost of delivering the software has skyrocketed.
Within the context of a front-end framework, the most ubiquitous pattern to differentiate the presentation of such mutually exclusive states is unquestionably component composition.
But when you get down to the most atomic of components, you start having to differentiate the atoms you use to handle mutually exclusive situations.
As far as creating an intuitive component API goes, that’s just not ergonomic.
Having to differentiate between
<InfoAlert />, etc. in your codebase is slightly more of a cognitive load than having one alert that accepts a
type prop, as in
<Alert type="warning" />.
In my experience, the more atomic and reusable a component is, the more it makes sense to control its behavior with props. This pattern also manifests itself as a solution when the level of effort to compose a separate component with a large area of overlapping functionality is significantly greater than simply exposing alternate props. This keeps things DRY and prevents reinventing the wheel.