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

Rule proposal: Warn against using an arrow function/anon fn when declaring a component #690

Closed
tleunen opened this issue Jul 18, 2016 · 7 comments

Comments

@tleunen
Copy link

tleunen commented Jul 18, 2016

Component should be named, and arrow functions are anonymous functions, so they produce unnamed components.

Even if Babel currently transforms an anonymous function into a named function, and even if Chrome currently set a name (fn.name) when assigning it to a variable, I believe it would be best to add a rule to warn against the use of arrow functions.

For example, when using jsdom and enzyme to test components built with arrow functions, we can get errors messages like this one because the component name was not set: expected the node in <??? /> to have....

So having a specific rule rule would help waning against arrow and anonymous function in general would help for this.

@ljharb
Copy link
Member

ljharb commented Jul 18, 2016

Perhaps it could be more generic and be configurable to require/allow specific function kinds for SFCs.

@gaearon
Copy link
Collaborator

gaearon commented Jul 19, 2016

Even if Babel currently transforms an anonymous function into a named function, and even if Chrome currently set a name (fn.name) when assigning it to a variable, I believe it would be best to add a rule to warn against the use of arrow functions.

Why? Per spec, the name will be assigned, so it’s fine.
(FWIW the official position is that arrow functions work well as components, and we might use this pattern in the documentation.)

@ljharb
Copy link
Member

ljharb commented Jul 19, 2016

@gaearon but in practice it is not always assigned. In general, explicit > implicit, and a linter rule to require explicit names by disallowing arrow functions is appropriate.

@gaearon
Copy link
Collaborator

gaearon commented Jul 20, 2016

Can you help me understand in which situations it wouldn’t get assigned?

@ljharb
Copy link
Member

ljharb commented Jul 20, 2016

@gaearon In the Babel repl, this function has no name:

export default (props) => {
  return <div {...props} />;
}

which thus would necessitate:

const Foo = (props) => {
  return <div {...props} />;
};
export default Foo;

but export-defaulting one thing only from a file inline is also a best practice according to the Airbnb styleguide.

In node 4 and later, if you do const foo = () => {};, foo.name is the empty string - I don't know the exact range of node and Chrome versions that this applies to, since the latest Chrome does have name inference, but there are many implementations in the wild that support arrow functions but not name inference.

@bkozera
Copy link

bkozera commented Dec 7, 2016

+1 from me.

Reasons:

  • Airbnb suggests that in their guide (unfortunately not explaining why)
  • Makes it easy to have consistency when writing stateless components across team (could have also opposite version forcing fat arrow)
  • There is a bug in jest (actually in istambul) where jest --coverage is sometimes failing. Changing to function from fat arrow did solve that for us.

@TheTFo
Copy link

TheTFo commented Feb 27, 2017

+1, I got caught by the Jest bug pointed out by bkozera, had to rewrite components to not use the fat arrow

edmorley added a commit to mozilla/treeherder that referenced this issue Mar 2, 2018
Since otherwise it's an anonymous function where the name has to be
inferred, which doesn't work in all cases:
https://github.com/airbnb/javascript/blob/master/react/README.md#class-vs-reactcreateclass-vs-stateless

Unfortunately there is not yet an ESLint rule to enforce this:
jsx-eslint/eslint-plugin-react#690
edmorley added a commit to mozilla/treeherder that referenced this issue Mar 2, 2018
Since otherwise it's an anonymous function where the name has to be
inferred, which doesn't work in all cases:
https://github.com/airbnb/javascript/blob/master/react/README.md#class-vs-reactcreateclass-vs-stateless

Unfortunately there is not yet an ESLint rule to enforce this:
jsx-eslint/eslint-plugin-react#690
ljharb pushed a commit to stefan-wullems/eslint-plugin-react that referenced this issue Oct 12, 2019
stefan-wullems pushed a commit to stefan-wullems/eslint-plugin-react that referenced this issue Nov 30, 2019
stefan-wullems pushed a commit to stefan-wullems/eslint-plugin-react that referenced this issue Jan 10, 2020
ljharb pushed a commit to stefan-wullems/eslint-plugin-react that referenced this issue Jan 11, 2020
@ljharb ljharb closed this as completed in 99cea84 Jan 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants