Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)
like image 201
Leo Farmer Avatar asked Apr 10 '19 20:04

Leo Farmer


People also ask

What is React displayName?

Prevent missing displayName in a React component definition (react/display-name) DisplayName allows you to name your component. This name is used by React in debugging messages.

What is a React memo?

React. memo is a higher order component. If your component renders the same result given the same props, you can wrap it in a call to React. memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.

How do you create a React class?

Create a Class Component When creating a React component, the component's name must start with an upper case letter. The component has to include the extends React. Component statement, this statement creates an inheritance to React. Component, and gives your component access to React.

What is functional component in Reactjs?

The first and recommended component type in React is functional components. A functional component is basically a JavaScript/ES6 function that returns a React element (JSX). According to React's official docs, the function below is a valid functional component: function Welcome(props) { return <h1>Hello, {props.


6 Answers

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 ;)

like image 101
Loïc Goyet Avatar answered Oct 05 '22 02:10

Loïc Goyet


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>
        },
    }
]
like image 43
kagundajm Avatar answered Oct 05 '22 02:10

kagundajm


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"
  }
}
like image 44
Arosha Avatar answered Oct 05 '22 03:10

Arosha


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,
  }
]
like image 42
avatar Avatar answered Oct 05 '22 04:10

avatar


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.

like image 33
ericsoco Avatar answered Oct 05 '22 02:10

ericsoco


Using anonymous functions and arrow functions will keep ESLint: Component definition is missing displayName (react/display-name) coming out, I guess this is because that when we are rendering a component through a function, we are giving them a displayName by naming the render function as well.

But using the normal function isn't enough, you might still meet the following warning:

Warning: Functions are not valid as a React child. This may happen if you return a Component instead of <Component /> from render. Or maybe you meant to call this function rather than return it.

You have to execute the normal function just right after render it. I passed the two rules by using the following code.

render: () => {
    return (function Actions() {
        return (
            <Button>
            View
            </Button>
                );
            })();
        },
like image 26
SiegeSailor Avatar answered Oct 05 '22 03:10

SiegeSailor