Eslint-plugin-react: react/jsx-no-useless-fragment false positive

Created on 3 Mar 2020  路  9Comments  路  Source: yannickcr/eslint-plugin-react

There's a false positive on the rule with forwarded children. Use cases are pretty rare but still exist. Without a fragment around the children, code breaks at runtime

const HollowComponent = ({ children }) => {
  // some logic here
  return <>{children}</>; // doesn't pass the rule
}

example: https://codesandbox.io/s/icy-lake-ri3uo

Temporary fix is to disable rule for this line but it would be nicer if this rule let this kind of Fragment use possible.

help wanted

Most helpful comment

Hi, I think I have encountered a similar problem. My use case is like this:

<Query>
  {({data, loading})  => {
    ...
    return (
      <>
        {anArray.map(item => {
          return item.success
            ? getTypeA(item)
            : getTypeB(item);
        })}
      </>
    );
  }
}
</Query>

This is treated as an error but the render prop expects the return to be a single element so I think the Fragment is necessary here.

All 9 comments

What use cases would require the fragment?

Here are 2 use cases I actually encounter in the project I'm working on.

1. Conditional rendering

Let's say we have a component augmenting its children conditionally like the following:

const Augmenter = ({ children }) => {
  // ... logic used here ...
  const tempJsx = (
    <>
      {additionalNodes}
      {children}
      {otherAdditionalNodes}
    </>
  )
  return renderWithAugmentations
    ? tempJsx
    : <>{children}</>
}

2. Testing hooks (mocks)

const MockComponentUseSomeHook = ({ children }) => {
  useSomeHook()
  return <>{children}</>
};

In the first case, why wouldn't : children work identically?

Same question in the second case; return children should work fine.

As you can see in the codesandbox I pasted in the original post ( https://codesandbox.io/s/suspicious-sunset-ly9ik ), returning the children without a fragment can throw a runtime error (in case no children are provided).

Working with typescript generates an error too as children type for a FunctionalComponent can be undefined and said functional component cannot return the undefined type.

Thanks for bearing with me.

Type errors aren't relevant, but runtime errors are.

The solution in your code, of course, is to use defaultProps, or const TestEmpty = ({ children = null }) => children;, so that if it is undefined, it becomes null, or, const TestEmpty = ({ children }) => children ?? null;, but it seems reasonable to have an option to specifically allow a prop, only, to be used with an otherwise "unnecessary" fragment, because of undefined.

Thank you for trying to understand the issue! I'll try the null workaround in my project which seems reasonable!

Hi, I think I have encountered a similar problem. My use case is like this:

<Query>
  {({data, loading})  => {
    ...
    return (
      <>
        {anArray.map(item => {
          return item.success
            ? getTypeA(item)
            : getTypeB(item);
        })}
      </>
    );
  }
}
</Query>

This is treated as an error but the render prop expects the return to be a single element so I think the Fragment is necessary here.

I have the same issue where I'm getting an error when there's a single map function inside the fragment. I can't enable this rule and use typescript at once because of this issue.

Same error as zenefits-brody and geoguide.

There's only one child in program's AST, but there may be multiple children in React tree.

https://github.com/yannickcr/eslint-plugin-react/blob/master/lib/rules/jsx-no-useless-fragment.js#L106

One should check if the only child isn't jsx expression with a call expression inside.

Edit: Function call like .map can also return undefined so dropping the fragment in this case could result in runtime error.

Was this page helpful?
0 / 5 - 0 ratings