Eslint-plugin-react: jsx-uses-react rule does not detect jsxFrag rule

Created on 11 Feb 2019  路  15Comments  路  Source: yannickcr/eslint-plugin-react

In babel, if one does not use jsxFrag, fragment syntax always requires React import (to use React.Fragment).
However, jsx-uses-react rule does not check this pragma and does not require React import when jsx pragma is set.
I think the rule should check jsxFrag pragma too and mark React as used if there is no jsxFrag pragma.

Most helpful comment

If this is still causing anyone pain (especially https://github.com/emotion-js/emotion/issues/1549 folks, since #2158 appears to be stalled), I threw together a plugin that re-implements jsx-uses-react and react-in-jsx-scope for Fragments specifically. This could be useful as a reference implementation for this issue, but I didn't feel like I understood the other ecosystem implications of how jsxFrag is used. @justingrant

It could be possible to implement something more general for jsxFrag support in jsx-uses-react and react-in-jsx-scope, but I'm not sure how this fits into everything else.

All 15 comments

What is jsxFrag?

It's nice that babel supports that comment syntax, but this eslint plugin does not, and never has done.

What this plugin supports is explicit settings in your eslint config: https://github.com/yannickcr/eslint-plugin-react#configuration . It's missing from that documentation, but it's looking for a pragma setting called "fragment", as you can see here.

A PR to add that pragma to the readme would be much appreciated.

@ljharb As far as I know, the rule supports comment pragma. Am I wrong?
If there is any other context, could you let me know?

It looks like following util does not check pragma comment of jsx, but not of jsxFrag.
https://github.com/yannickcr/eslint-plugin-react/blob/4270205f3c22dd466cebb80cae7c46e67044acda/lib/util/pragma.js#L36-L54

I suppose we could accept a PR that added that support - presumably it's new, with React 16.2.

I notice that this is not simple as I thought.
First of all, current shared setting options do not support different namespaces for jsx and jsxFrag. For example,

import { jsx } from 'my-jsx-element-creator';
import React from 'react';

(
  <>
    <div />
  </>
);

cannot be represented with current options.
IMO, this package should use something like jsxPragma and jsxFragPragma whose default values are React.createElement and React.Fragment.
Could you give your opinion, @ljharb?

I'm a bit confused why createElement and Fragment would come from different packages. Can you explain the use case?

For example, emotion@10 uses custom jsx creator to support css props. However, it uses React.createElement under the hood, so there is no reason to make a new type of Fragment and it should not make one.
Likewise, one can use a custom jsx creator to extend library features, but it's just an extension so it should reuse Fragment type.

I suppose that makes sense, but it's a bunch of extra complexity.

Yes, that's what I mean. This issue is not that simple as I originally thought.

@Ailrun @ljharb - I ended up here after running into https://github.com/emotion-js/emotion/issues/1549. If I'm understanding that issue, the <> shorthand for Fragment is broken with the current versions of emotion and eslint-plugin-react, because:
1) if you import React from 'react' and don't otherwise use React, then eslint will complain that 'React' is defined but never used. (no-unused-vars) (example: https://codesandbox.io/s/pensive-edison-bdkpp)
2) But if you don't import React from 'react', then you'll get a runtime error React is not defined because React.Fragment is emitted into the final transpiled code without React being imported.

In this comment, @Andarist says that emotion can't solve (2), and recommends that eslint-plugin-react could help . Is there already an eslint-plugin-react rule that can solve (2) instead, presumably by not triggering the no-unused-vars if the unused var is React and the file contains <>? Or is that solution what #2158 is trying to address? If the latter, then what's needed to get #2158 over the finish line?

Yes, jsx-uses-vars may need to be updated for fragment syntax.

If this is still causing anyone pain (especially https://github.com/emotion-js/emotion/issues/1549 folks, since #2158 appears to be stalled), I threw together a plugin that re-implements jsx-uses-react and react-in-jsx-scope for Fragments specifically. This could be useful as a reference implementation for this issue, but I didn't feel like I understood the other ecosystem implications of how jsxFrag is used. @justingrant

It could be possible to implement something more general for jsxFrag support in jsx-uses-react and react-in-jsx-scope, but I'm not sure how this fits into everything else.

@jaronheard it's only stalled because the PR author has withdrawn; anyone can move it along by posting a link to an updated branch (NOT a new PR) :-)

Was this page helpful?
0 / 5 - 0 ratings