ReactJS - How can I access the displayName of a component using javascript?

I'm building some React components and sometimes would like to log to the console the type of component that's being rendered, by displayName, which JSX uses when displaying the name of a component.

From the context of a component, how can I access the displayName property?

e.g. how can I make the console.log statement in this example show the displayName of the component?

var Hello = React.createClass({
    displayName: 'HeyHey',

    render: function() {
        console.log(this.displayName);

        return <div>Hello {this.props.name}</div>;
    }
});

Intended output in console:

HeyHey


It's available as the public property this.constructor.displayName.


Below is a full code snippet illustrating in detail how to both get and set the 'name' of both class Components and stateless functional Components.

You get a name property on a Component for free, from name of the class Component or the stateless functional Component in code. However be aware that this will be undefined in the case of anonymous classes/functions, and can also be wiped out / changed by code minification.

You may define a custom displayName property on the class Component or stateless functional Component, if you need to customise. This is especially useful for higher order components. It will also always survive minification.

On a class, and here is the part that may not be obvious, the name and displayName are properties on the class itself. Thats why from within the Component instance you have to use this.constructor.name / this.constructor.displayName and with a reference to the Component instance you use Component.name / Component.displayName. The code below shows this in practice.

Best practice for using a Component's name seems to be:

  • Try to use displayName
  • If that's undefined, try to use name
  • It that's undefined, fall back to a hardcoded string like 'Component' / 'Anonymous'

class ClassComponent extends React.Component {
  componentDidMount () {
    if (!this.props.wrapped) {
      console.log('ClassComponent')
      console.log(`  displayName: ${this.constructor.displayName}`)   
      console.log(`  name: ${this.constructor.name}\n\n`)
    }
  }
  
  render () { 
    return <div>ClassComponent {this.props.wrapped && '(wrapped)'}</div> 
  }
}

ClassComponent.displayName = 
  'ClassComponentCustom'

const SFComponent = (props) => (
  <div>SFComponent {props.wrapped && '(wrapped)'}</div>
)

SFComponent.displayName =     
  'SFComponentCustom'

const wrap = (WrappedComponent) => {
  class Wrapper extends React.Component {
    componentDidMount () {
      console.log('HOC')
      console.log(`  displayName: ${this.constructor.displayName}`)   
      console.log(`  name: ${this.constructor.name}`)
      console.log(`  wrapping a Component with:`)
      console.log(`    displayName: ${WrappedComponent.displayName}`)   
      console.log(`    name: ${WrappedComponent.name}\n\n`)
    }
    
    render () {
      return <WrappedComponent wrapped />
    }
  }
  
  // for the wrapped component
  // check for displayName for something more descriptive, 
  // else fall back to name
  const wrappedComponentName = 
    WrappedComponent.displayName ||
    WrappedComponent.name
    
  Wrapper.displayName =
    `WrapperCustom<${wrappedComponentName}>`
    
  return Wrapper
}
  
const WrappedClassComponent = wrap(ClassComponent)
const WrappedSFComponent = wrap(SFComponent)  

const Example = () => (
  <div className="example">
    <ClassComponent />
    <SFComponent />
    <WrappedClassComponent />
    <WrappedSFComponent />
  </div>
)

ReactDOM.render(
  <Example />, 
  document.getElementById('root')
)
.example > div {
  font-family: 'Arial';
  font-size: 14px;
  padding: 5px 10px;
  margin-bottom: 10px;
  background: rgb(240,240,240);
  border-radius: 4px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

You can find it on this._descriptor.type

Hello <div>{this._descriptor.type.displayName}</div>

demo

Only use this for testing; it might stop working at any point. It's unlikely to work in 0.12.