Reputation: 10878
I'm trying to make my own Tabs
component, so that I can use tabs in my app. However I seem to be having issues trying to extract the child components I need by type.
import React from 'react'
export class Tabs extends React.Component {
render() {
let children = this.props.children
let tablinks = React.Children.map(children, x => {
console.log(x.type.displayName) // Always undefined
if (x.type.displayName == 'Tab Link') {
return x
}
})
return (
<div className="tabs"></div>
)
}
}
export class TabLink extends React.Component {
constructor(props) {
super(props)
this.displayName = 'Tab Link'
}
render() {
return (
<div className="tab-link"></div>
)
}
}
<Tabs>
<TabLink path="tab1">Test</TabLink>
<TabLink path="tab2">Test2</TabLink>
</Tabs>
My console.log
never returns "Tab Link", it always returns undefined
, why?
Upvotes: 8
Views: 15741
Reputation: 441
I'm wondering why does your Tabs
component need to know how to render each children.
You could have a specific component for each type of tab, with their own styles and with 2 props: isSelected
and onSelect
.
Then the Tabs
would only:
onSelect
of each tab (to update the selectedTab state and to pass true in the isSelected
prop of the correct tab)Upvotes: 0
Reputation: 2546
You can use the already defined name
property:
if (x.type.name === TabLink.name) {
return x
}
I recommend to use TabLink.name
instead of 'TabLink'
string for better maintenance.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name
Upvotes: 3
Reputation: 20027
As an alternative you could use
console.log(x.type.name) // this would be 'TabLink'
You don't need to explicitly define displayName in this case.
https://jsfiddle.net/lustoykov/u1twznw7/1/
Upvotes: 14