ESLint: Component definition is missing displayName (react/display-name)

51,526

Solution 1

ESLint thinks you are defining a new component without setting any name to it.

This is explained because ESLint cannot recognize the render prop pattern because you are not directly writing this render prop into a component, but into an object.

You can either put the render prop directly into your jsx implementation of the <Column> component,

 const columns_payment_summary_table_render = text => (<span>{getCountForCountry(text)}</span>);
 const columns_payment_summary_table = [{
    title: SettlementConstants.LABEL_QUANTITY_SELECTED, 
    dataIndex: "group", 
    key: "group",        
    // eslint-disable-next-line react/display-name        
    render: columns_payment_summary_table_render
 }];

or shut down the ESLint's error by doing this :

const columns_payment_summary_table = [ 
    {
        title: SettlementConstants.LABEL_QUANTITY_SELECTED,
        dataIndex: 'group',
        key: 'group',
        // eslint-disable-next-line react/display-name
        render: text => (
            <span>{getCountForCountry(text)}</span>
        ),
    }
]

I hope it helped ;)

Solution 2

Using a normal function for the render key will also remove the ESLint warning without any need for disabling the warning.

const columns_payment_summary_table = [ 
    {
        title: SettlementConstants.LABEL_QUANTITY_SELECTED,
        dataIndex: 'group',
        key: 'group',
        render: function countForCountry(text) {
            return <span>{getCountForCountry(text)}</span>
        },
    }
]

Solution 3

If anyone needs to avoid this in all the files, add below to the rules section of .eslintrc.js file,

{
  ...
  "rules": {
    "react/display-name": "off"
  }
}

Solution 4

Sometimes we can bypass rules if we have an error in only one or two places. What if we have the same use case in multiple places. Each time We have to disable rules.

Instead, we can bypass this error by assigning function to render property.

const getMyHTML = (text) => <span>{getCountForCountry(text)}</span>
const columns_payment_summary_table = [
  {
    title: SettlementConstants.LABEL_QUANTITY_SELECTED,
    dataIndex: 'group',
    key: 'group',
    render: getMyHTML,
  }
]

Solution 5

This is covered pretty thoroughly in this ESLint issue.

As Loïc suggested, suppressing the lint error is the simplest option here.

However, the lint error exists for a reason -- displayName can be helpful for debugging, particularly in React DevTools' Component view. The easiest way to assign your function a displayName is to use a named function declaration, and hoist the definition:

function renderTable(text) {
  return (<span>{getCountForCountry(text)}</span>);
}
const columns_payment_summary_table = [
  {
    title: SettlementConstants.LABEL_QUANTITY_SELECTED,
    dataIndex: 'group',
    key: 'group',
    render: text => (
      <span>{getCountForCountry(text)}</span>
    ),
  }
]

That's obviously more verbose, though, and if you don't anticipate needing to find the rendered component by name in DevTools, it's simplest to just suppress the error.

Share:
51,526

Related videos on Youtube

Leo Farmer
Author by

Leo Farmer

Software developer from the 'City of Sails' (Auckland, New Zealand)

Updated on June 18, 2021

Comments

  • Leo Farmer
    Leo Farmer over 1 year

    I'm using a react hook component with antd. When setting up columns for a table, the render function is giving me an ESLint error:

    ESLint: Component definition is missing displayName (react/display-name)

    I've tried adding displayName to the object but this doesn't work.

    This is how the error looks: enter image description here

    This is the code:

    const columns_payment_summary_table = [ 
        {
          title: FooConstants.LABEL_QUANTITY_SELECTED,
          dataIndex: 'group',
          key: 'group',
          render: text => (
            <span>{getCountForCountry(text)}</span>
          ),
        }
      ]
    

    Can anyone help?

    Here is full component code (well just the relevant bits)

    import * as FooConstants from './constants'
    import {connect} from 'react-redux'
    import React, {useState, useEffect} from 'react'
    import {Card, Table} from 'antd'
    import PropTypes from 'prop-types'
    const propTypes = {
      foos: PropTypes.object.isRequired,
    }
    function Foos(props) {
      const [selectedFooRows, setSelectedFooRows] = useState([])
      useEffect(() => {
        getFooDetails()
      }, [])
      function getFooDetails() {
        props.dispatch({
          type: FooConstants.GET_FOO_PAYMENT_SUMMARIES,
          params: {
            'group_by': 'country_code',
            'type': FooConstants.CLAIM_FOO,
          }
        })
        props.dispatch({
          type: FooConstants.GET_FOO_PAYMENTS,
          params: {'type': FooConstants.CLAIM_FOO, }
        })
      }
      const columns_payment_summary_table = [
        {
          title: FooConstants.LABEL_QUANTITY_SELECTED,
          dataIndex: 'group',
          key: 'group',
          render: text => (
            <span>{getCountForCountry(text)}</span>
          ),
        }
      ]
      function getCountForCountry(country_code){
        let selected_country = selectedFooRows.filter(function(row){
          return row.group === country_code
        })
        if(selected_country && selected_country.length > 0){
          return selected_country[0].ids.length
        } else {
          return 0
        }
      }
      return (
        <div>
          <Card
            title={FooConstants.LABEL_FOO_SUMMARY}>
            <Table
              columns={columns_payment_summary_table}
              bordered={true}
              dataSource={props.foos.foo_payment_summaries}
              loading={props.foos.foo_payment_summaries_pending && !props.foos.foo_payment_summaries}
              rowKey={record => record.group}
            />
          </Card>
        </div>
      )
    }
    Foos.propTypes = propTypes
    const mapStateToProps = (state) => {
      return {foos: state.foosReducer}
    }
    export default connect(
      mapStateToProps,
    )(Foos)
    
    • duc mai over 3 years
      did you look at this github.com/yannickcr/eslint-plugin-react/blob/master/docs/ru‌​les/…? can you post your component code?
    • Leo Farmer
      Leo Farmer over 3 years
      @duc-mai Yes, but I don't see the solution to my issue there. I've tried adding displayName to the object, but that doesn't fix the issue. I can see the issue is caused by the render method of the antd column, but I can't work out how to fix it.
  • Leo Farmer
    Leo Farmer over 3 years
    I already know how to shut down eslint errors ;-) Please can you expand on the "You can either put the render prop directly into your jsx implementation of the <Column> component" part of your answer.
  • Loïc Goyet over 3 years
    Just set the function defined as value of the render key into its own variable and it should be good.
  • Loïc Goyet over 3 years
    js const columns_payment_summary_table_render = text => ( <span>{getCountForCountry(text)}</span> ) const columns_payment_summary_table = [ { title: SettlementConstants.LABEL_QUANTITY_SELECTED, dataIndex: 'group', key: 'group', // eslint-disable-next-line react/display-name render: columns_payment_summary_table_render, } ]
  • Leo Farmer
    Leo Farmer over 3 years
    That did help! Thank you very much.
  • Juan Lanus
    Juan Lanus almost 3 years
    I tried this in a different context, where my code is a method of a non-React class (does not extend Component). Firstly I wrote renderX = ( x ) => <p>{ x }</p> and got error. After seeing this a added the missing name renderX = function renderX( x ){ <p>{ x }</p> } The first version is an anonymous function assigned to an object member. The second one is a named function assigned to the same member.
  • lony
    lony over 2 years
    Came across this issue github.com/yannickcr/eslint-plugin-react/issues/2404 if someone wants to track a permanent solution