eslint-plugin-react: False positive display-name when using forwardRef

Tell us about your environment

  • ESLint Version: 5.16.0
  • Node Version: 10.12.0
  • npm Version: 6.9.0

What parser (default, Babel-ESLint, etc.) are you using? babel-eslint 10.0.1

Please show your full configuration:

Configuration
module.exports = {
    "env": {
        "browser": true,
        "es6": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended"
    ],
    "parserOptions": {
        "ecmaVersion": 9,
        "sourceType": "module",
        "ecmaFeatures": {
            "jsx": true
        }
    },
    "rules": {
        "indent": [
            "error",
            2,
            { "SwitchCase": 1 }
        ],
        "linebreak-style": [
            "error",
            "unix"
        ],
        "no-console": "warn",
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "always"
        ]
    }
};

What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.

import PropTypes from 'prop-types';
import React from 'react';

const Paragraph = React.forwardRef(function Paragraph({ style }, ref) {
  // const finalStyle = Object.assign({}, style);
  return <div ref={ref} style={style} />;
});

Paragraph.propTypes = {
  style: PropTypes.object
};

export default Paragraph;
export const proptype = Paragraph.PropTypes;
npx eslint <file>

What did you expect to happen? Nothing as the file is valid

What actually happened? Please include the actual, raw output from ESLint.

  4:19  error  Component definition is missing display name  react/display-name

✖ 1 problem (1 error, 0 warnings)

Fun fact! If you uncomment the line with Object.assign, the false positive disappears…

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 13
  • Comments: 25 (18 by maintainers)

Commits related to this issue

Most upvoted comments

I have pretty the same issue with React.memo, and as it was explained, I did the same for forwardRef - and error disappeared.

import PropTypes from 'prop-types'
import React from 'react'

function Paragraph({ style }, ref) {
  return (<div ref={ref} style={style} />)
}

Paragraph.propTypes = {
  style: PropTypes.object
};

export default React.forwardRef(Paragraph)
import PropTypes from 'prop-types';
import React from 'react';

const Paragraph = React.forwardRef(({ style }, ref) => {
  const finalStyle = Object.assign({}, style);
  return <div ref={ref} style={finalStyle} />;
});

Paragraph.displayName = 'Paragraph';
Paragraph.propTypes = {
  style: PropTypes.object
};

export default Paragraph;
export const proptype = Paragraph.PropTypes;

I completely agree with @Hypnosphi, without a .name or .displayName debugging can be a nightmare.

Simple example:

Before upgrading to Unicorn, I just had:

import React, { forwardRef } from 'react'

const Button = forwardRef(({ className, active, ...props }, ref) => (
    <span {...props} ref={ref} className={`${className} ${active ? 'active' : ''}`} />
))

Was erroring out (for a reason not shown above), and was just showing me forwardRef in the error handler and it took me a bit to find where the issue was. Simply adding Button.displayName = 'SlateToolbarButton' would have saved me some time.

const Button = forwardRef(({ className, active, ...props }, ref) => (
    <span {...props} ref={ref} className={`${className} ${active ? 'active' : ''}`} />
))

Button.displayName = 'SlateToolbarButton'

From rule motivation:

This name is used by React in debugging messages

React uses getComponentName function in those messages. In case of forwardRef, it derives the name from type.render which is the function passed to forwardRef. Third party tools like Enzyme use a similar logic.

So the fact that this function is not a component doesn’t mean that its name (or even .displayName) has no effect on the actual displayed name

Heh, well since when I upgraded I got 7.20.0, and that changelog only goes to 7.16.0…I’m not sure what to think Sorry I must be getting mixed up with another package, I do have 7.16.0. But that at least tells me I have all the fixes in the changelog

@davidwieler the question is, whether the following work as well. I say that the following is just as good it terms of debugging, note the named function:

const Button = forwardRef(function StateToolbarButton({ className, active, ...props }, ref) {
    return <span {...props} ref={ref} className={`${className} ${active ? 'active' : ''}`} />
})

Can you please check it in your setup if you have any doubts?