Composition beats configuration
Every flag you add anticipates a need. Every slot you leave open supports the needs you did not anticipate.
A Modal with showCloseButton, showFooter, footerAlign, headerIcon and dismissible has tried to predict the future and will keep growing. A Modal that renders children, with Modal.Header, Modal.Body and Modal.Footer available to compose, supports arrangements you never thought of and never needs another boolean.
Compound components share state implicitly through context that the parent provides and the parts consume, so <Tabs><Tabs.List><Tabs.Tab/></Tabs.List><Tabs.Panel/></Tabs> works with no wiring visible to the user. The cost is that the parts are meaningless outside the parent, which is fine if you make that a clear error rather than an undefined.
Render props and hooks solve the inverse problem: sharing behaviour rather than structure. A hook that owns the logic and returns the state and handlers lets every consumer render whatever they like, which is the whole basis of headless component libraries. The rule of thumb is that structure composes with children and behaviour composes with hooks, and confusing the two produces the awkward abstractions.
You should now be able to
- Convert a configuration prop into a composition slot
- Design a compound component with a shared implicit state
Loading…