Say I have a <Modal> that takes a <Header> <Content> and <Footer>.
(
<Modal>
<Header>Foo</Header>
<Content>Foo</Content>
<Footer>Foo</Footer>
</Modal>
)
Now, inside my Modal component I'll probably have code like the following:
const header = children.find(child => child.type === Header)
In order to get a reference to the rendered header.
Now, what if from the consumer of the modal, I needed a decorated Header. Let's just call it DecoratedHeader
// DecoratedHeader
const DecoratedHeader = () => <Header>Foo <Icon type="lock" /></Header>
// consumer
(
<Modal>
<DecoratedHeader />
<Content>Foo</Content>
<Footer>Foo</Footer>
</Modal>
)
The line above wouldn't work anymore, as DecoratedHeader type is not Header. However, it IS rendering a Header.
It feels like there's the concept of "interface" which is missing. Ultimately, the Modal cares for a Header to be rendered, but if you wrap it under a "custom" component there's no way for it to know that it is still a Header.
What am I missing?
EDIT
To expand more about my use cases, I don't need an alternative solution. I need to know whether React has support for a mechanism equivalent to an interface, where 2 different Components that comply with the Liskov Substitution Principle (meaning they're swappable) can have a way to be picked by the parent.
Specifically, replacing this "hardcoded implementation" search, with an "interface" search:
-const specificChild = children.find(child => child.type === SomeComponent)
+const componentInterface = children.find(child => ????)
// Get a prop out of that component interface
const { someInterfaceProp } = componentInterface.props;
return (
<div>
{componentInterface} {/* render it on a specific place */}
</div>
)