jsx-eslint/eslint-plugin-react

New `prefer-arrow-children` rule

Open

#2617 opened on Apr 6, 2020

View on GitHub
 (11 comments) (0 reactions) (0 assignees)JavaScript (8,630 stars) (2,797 forks)batch import
enhancementhelp wanted

Description

Consider the following snippet:

export const BarComponent: React.FunctionComponent<{
  children(arg: number): React.ReactNode;
}> = ({ children }) => <div>{children(42)}</div>;

export const FooComponent: React.FunctionComponent = () => (
  <BarComponent>
    {function bar(x) {
      return <>This is x: {x}</>;
    }}
  </BarComponent>
);

We are currently transitioning from TSLint to ESLint, and the no-function-expression rule of https://github.com/microsoft/tslint-microsoft-contrib was catching this in favor of:

export const FooComponent: React.FunctionComponent = () => (
  <BarComponent>{x => <>This is x: {x}</>}</BarComponent>
);

There are a bunch of rules helping in some ways for this, but not this specific situation:

  • prefer-arrow-callback helps ensuring [1, 2, 3].map(x => x * 2) is preferred over [1, 2, 3].map(function (x) { return x * 2; }) but as far as I know has no effect on JSX props/children
  • react/jsx-no-bind (which we set up with allowArrowFunctions: true) helps ensuring something similar with props: onClick={() => setFoo(true)} is preferred over onClick={function () { return setFoo(true); }}

I am not aware of a rule or configuration that would ensure arrow functions are used with children props expecting functions. Is there such thing? If not, would it make sense as a new rule?

I know of eslint-plugin-prefer-arrow which enforces all functions to be arrow functions. It is however very strict and we cannot use it as is because we have hundreds of top-level function declarations (we were using allow-declarations and allow-named-functions of only-arrow-functions).

Contributor guide