Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Component definition is missing display name" with React.createElement #597

Closed
nihey opened this issue May 12, 2016 · 13 comments
Closed

"Component definition is missing display name" with React.createElement #597

nihey opened this issue May 12, 2016 · 13 comments

Comments

@nihey
Copy link

nihey commented May 12, 2016

Hello eslint-plugin-react maintainers, your plugins has surely been of great help so far :)

But I recently had problems with react/display-name rule, I have several functions that return React.createElement instances on my code, and they seem to be triggering react/display-name rule, even though I'm not creating a Component.

I have isolated the problem on the following code:

var Utils = {
  label: function(settings) {
    return <span className={'label ' + settings.klass}>{ settings.text }</span>;
  },
};

export default Utils;

The minimal .eslintrc code I need to make that work is:

{
  "rules": {
    "react/display-name": [2],
  },
  "parserOptions": {
    "sourceType": "module",
    "ecmaFeatures": {
      "jsx": true
    }
  },
  "plugins": [
    "react",
  ]
}

As I am seeing this, the Utils.label function should not be triggering react/display-name rule. A <span></span> instance will generate a React.createElement instance, so no displayName should be required for it, right?

Edit:

This may be related to: #512

@ljharb
Copy link
Member

ljharb commented May 12, 2016

A function that returns jsx (ie, that generates a React.createElement) is in fact a stateless functional component - so the rule would expect it to have a display name, propTypes, etc.

You're also correct that any solution to #512 would also work here. However, for now I'd recommend just disabling the rule on that line/file.

@Jessidhia
Copy link
Contributor

Jessidhia commented Jul 20, 2016

It seems this is also triggered when using thunks that return ReactElements (...which look very similar to a SFC, but are not quite the same).

Here's an example, where t is a function that, for the given arguments, returns ['String with ', <a href='/'>{'replacement'}</a>, '']:

<span>
  {t('String with %(a:replacement)', {
    a: text => <a href='/'>{text}</a> /* react/display-name warns here */
  })}
</span>

@mjackson
Copy link
Contributor

mjackson commented Aug 3, 2016

A function that returns jsx (ie, that generates a React.createElement) is in fact a stateless functional component

While such functions may be used as components (i.e. passed as the first arg to React.createElement), I think it's too aggressive to assume that all such functions are components. As render props become more and more common (ala react-motion and react-router) this is going to be a larger concern.

I'd say we can close this issue as a dup of #512

@ljharb
Copy link
Member

ljharb commented Aug 3, 2016

I agree this is a duplicate of #512.

@ljharb ljharb closed this as completed Aug 3, 2016
@sturmenta
Copy link

//warn
const wrapWithToastProvider = Comp => props => (
	<ToastProvider>
		<Comp {...props} />
	</ToastProvider>
);

//warn
function wrapWithToastProvider(Comp) {
  return function (props) {
    return (
		<ToastProvider>
			<Comp {...props} />
		</ToastProvider>
    );
  };
}

Any help?

@ljharb
Copy link
Member

ljharb commented Jul 24, 2018

@sturmenta neither of those is a named function:

function wrapWithToastProvider(Comp) {
  return function WrappedWithToast(props) {
    return (
		<ToastProvider>
			<Comp {...props} />
		</ToastProvider>
    );
  };
}

@nikolaisdfsd
Copy link

nikolaisdfsd commented Aug 5, 2019

@ljharb is it possible to do something similar with arrow functions?

const AppWrapper => Comp => props => <div><Comp {...props} /></div>

I thought that it should automatically pass AppWrapper as component's name

@ljharb
Copy link
Member

ljharb commented Aug 5, 2019

@Nikolai-S absolutely not; the language’s inference will never extend beyond your outer HOC. If you want your components to reliably have names, do not use arrow functions for them, ever.

@S4elkyn4eGGG
Copy link

"react/display-name": "off"

@phiresky
Copy link

The example in the original post here:

var Utils = {
  label: function(settings) {
    return <span className={'label ' + settings.klass}>{ settings.text }</span>;
  },
};

Is in fact a false positive of this rule, since the display name of the function is correctly set to the key in literal objects since ES6: https://2ality.com/2015/09/function-names-es6.html

For example:

const x = { foo: () => {} }

x.foo.name // === "foo" even though the function is an anonymous lambda

@ljharb
Copy link
Member

ljharb commented Mar 30, 2020

@phiresky you have to enable ignoreTranspilerNames to be able to rely on inference (which i don’t suggest doing)

@phiresky
Copy link

Ah, I didn't see there was a configurable option for that (link). Docs don't listing anything about it not being recommended. Why would you not suggest it?

@ljharb
Copy link
Member

ljharb commented Mar 30, 2020

Function name inference is specified, but not intuitive and will not always apply when one thinks it does. It's far, far better for debuggability to always and only use explicit names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

8 participants