jsx-eslint/eslint-plugin-react

New `prefer-arrow-children` rule

Open

#2,617 opened on Apr 6, 2020

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

Repository metrics

Stars
 (8,630 stars)
PR merge metrics
 (No merged PRs in 30d)

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