I'm building a REACT
App (with TypeScript), and I'm facing a problem which solution would require the possibility to identify the different REACT
children components. Basically, something like this:
const RibbonTab: ReactFC<IRibbonTab> = (props) => {
return <p>{props.header}</p>
}
const Ribbon: ReactFC<IRibbon> = (props) => {
const ribbonTabs = props.children.ofType<RibbonTab>(); // This is what I'd like to accomplish.
return <>props.children</>;
}
I've searched for a while, and many, if not all the accepted answers (like here: only allow children of a specific type in a react component), are to use type.displayName
(this.props.children[child].type.displayName
). Unfortunately, it has also been said that displayName
might be minified in production, so I just can't rely on that.
The only way I found out is to "force" a own display name. Basically, I create an interface IUniqueComponent
and then extends it for each component that should be identifiable. Something like this:
interface IUniqueComponent {
displayNameForIdentification: string;
}
const RibbonTab: ReactFC<IRibbonTab extends IUniqueComponent> = (props) => { ... }
RibbonTab.defaultProps = { displayNameForIdentification: "RibbonTab" }
And then, using React.Children.forEach
, I can filter the children:
React.Children.forEach(props.children, (c) => {
if (React.isValidElement(c)) {
if (c.props.displayNameForIdentification === 'WHAT I WANT') { ... }
}
})
What I don't like of this solution is the fact that I'm adding the identifier by myself, and even the props name, displayNameForIdentification
, is not saved by React somewhere safe, but it's just a prop: I've no certainty that a developer override that props (OK, I could just say "NEVER USE displayNameForIdentification
PROPS", but I'd like to avoid this).
So, is there any way to identify the type of REACT
children component?
EDIT: By following Ramesh suggestion, I can write something like this:
React.Children.forEach(props.children, (c) => {
if (React.isValidElement(c)) {
if (c.type.name === 'WHAT I WANT') { ... }
}
})
Though, TypeScript does not like c.type.name
, it gives me the following error, and I'm not able to solve it:
Property 'name' does not exist on type 'string | ((props: any) => ReactElement Component)>) | (new (props: any) => Component)'. Property 'name' does not exist on type 'string'.ts(2339)
Any suggestion on this newcomer?