admin管理员组

文章数量:1202195

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?

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?

Share Improve this question asked Aug 29, 2016 at 18:37 Sebastian OlsenSebastian Olsen 10.9k9 gold badges53 silver badges96 bronze badges 3
  • Did you mean to have TabLink extend Tabs? Right now it's just a sibling as it extends React.Component. – Jecoms Commented Aug 29, 2016 at 18:39
  • @Jecoms Wait, I have to extend Tabs? How would that work? Doesn't it need to extend React.Component to work? – Sebastian Olsen Commented Aug 29, 2016 at 18:40
  • I misunderstood your intent. I feel like x.type is the problem, but I'd have to research further. – Jecoms Commented Aug 29, 2016 at 18:53
Add a comment  | 

4 Answers 4

Reset to default 14

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/

It's undefined because displayName should be a static property.

class TabLink extends React.Component { 
  constructor(props) {
    super(props)
  }
  render() {
    return (
      <div className="tab-link"></div>
    )
  }
} 
TabLink.displayName = 'Tab Link'

jsfiddle (check the console)

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

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:

  1. Render its children, inline, with the correct space among them ("display:flex" with column-gap)
  2. Control the tab selection, by keeping the state of the selected tab and handling the onSelect of each tab (to update the selectedTab state and to pass true in the isSelected prop of the correct tab)

本文标签: javascriptHow to get children type in reactStack Overflow