Ozan Yurtsever
Ozan Yurtsever

Reputation: 1304

Retrieving the type of JSX children

I am facing with a challenge where I have to organize the child components depending on their type.

Let's say we have a parent component named Modal, defined as follows;

interface IModalProps {
    children: ModalHeader | ModalBody | ModalFooter;
}

function Modal({ children }: IModalProps) { ... }

And there are other children components that will be nested inside the parent Modal component;

function ModalHeader(props) { ... }
function ModalBody(props) { ... }
function ModalFooter(props) { ... }

What I want to do is to use these components in my index.tsx as follows;

<Modal>
    <ModalHeader />
    <div /> { /* Desired error: type 'div' does not exist in type 'ModalHeader | ModalBody | ModalFooter' */ }
    <ModalBody />
    <ModalFooter />
</Modal>

So by using the children property defined with the IModalProps interface, I can access to all of these nested components inside the Modal component, after nesting them as above. However, it will just give me the components inside an array, without me knowing what element represent which of the child components. I want to be able to identify the types of these child components inside my parent component, so that I can apply specific conditions or layouts by using them. For example, I may want to place the ModalHeader component inside a div where I apply special conditions and stylings, or I may want to set a specific display order as a layout constraint for all of the child components, by using the information about their types.

Are there any way for me to achieve that, without passing these components as named properties?

Thanks.

Upvotes: 1

Views: 29

Answers (1)

Charchit Kapoor
Charchit Kapoor

Reputation: 9284

You can compare the type property of the children's props to the relevant component type, or type.name property, in your Modal component, something like this:

React.Children.forEach(children, child => {
    if (child.type === ModalHeader || child.type.name === ModalHeader.name) {
        console.log('Header Component');
    }
});

Note: only one check is necessary (either type or type.name) depending on the version of the packages you are using.

Upvotes: 1

Related Questions