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.
What is jsxFrag?
@ljharb The documentation of the babel would be better than my explanation.
https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#custom-1
https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#pragmafrag
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) :-)
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-reactandreact-in-jsx-scopefor 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 howjsxFragis used. @justingrantIt could be possible to implement something more general for
jsxFragsupport injsx-uses-reactandreact-in-jsx-scope, but I'm not sure how this fits into everything else.