react-scoped-css
react-scoped-css copied to clipboard
Dealing with React Fragment
When using 'babel-plugin-react-scoped-css' with <Fragment>
, React gives a warning in DevTools Console:
Warning: Invalid prop
data-v-d2ab454f
supplied toReact.Fragment
. React.Fragment can only havekey
andchildren
props.
The component:
import React, {Component, Fragment} from 'react';
export default class Test extends Component {
constructor (props) {
super(props);
this.state = {};
}
render () {
return <Fragment>
<div>Part 1</div>
<div>Part 2</div>
</Fragment>;
}
};
Check this out, same issue https://github.com/gaoxiaoliangz/react-scoped-css/issues/2
Consider bypassing <Fragment>
by adding an option like pragmaFragIdentifier
to identify it.
Here is a solution:
- edit babel-plugin-react-scoped-css/index.js, add the commented code below
JSXElement(path, stats) {
if (!this.hasScopedCss || path.node.openingElement.name.type === 'JSXMemberExpression') {
return
}
// let { pragmaFragIdentifier } = stats.opts;
// if (pragmaFragIdentifier && path.node.openingElement.name.name === pragmaFragIdentifier) {
// return
// }
- edit babel run config, add an option
pragmaFragIdentifier
(just likepragmaFrag
for@babel/preset-react
)
{
"plugins": [
["babel-plugin-react-scoped-css", {
"pragmaFragIdentifier": "Fragment"
}]
]
}
- Optionally, let option
pragmaFragIdentifier
default to"Fragment"
I think may React developers use<Fragment>
, there are two issues raised so far. For developers who use custom JSX<Fragment>
, they may they may setpragmaFragIdentifier
to""
Sorry to be so verbose, I'm crafting a React project boilerlate for Vue.js-camp co-workers.
Consider a situation like this
const Select = {
Fragment: () => <div>fragment</div>
}
const App = () => {
return <Select.Fragment />
}
In this situation Select.Fragment
is supposed to receive data-v-*
prop but with the implementation above it won't.
My idea is not to add data-v-*
support on React Fragment, but to bypass(not to add data-v-* on) Fragment.
Assuming Fragment JSX can be written in 3 forms:
- Short syntax
<>
- JSXMemberExpression syntax like
<React.Fragment>
,<My.React.Fragment>
- Identifier syntax like
<Fragment>
,<ReactFragment>
Currently neither "Short syntax" nor "JSXMemberExpression syntax" will trigger the React warning mentioned above, but "Identifier syntax" like <Fragment>
will. thus I have to use <>
or <React.Fragment>
to avoid the warning.
Adding pragmaFragIdentifier
config doesn't seem to be a good idea, this job is supposed to be done by the plugin. Maybe it's just enough to just bypass adding data-v-*
for <>
, <Fragment>
and <React.Fragment>
. And let users known this behavior i'n the docs until we have a better solution.
Or maybe we can do a simple static analysis on the module to make sure Fragment
is actually exported from react.
Consider a situation like this
const Select = { Fragment: () => <div>fragment</div> } const App = () => { return <Select.Fragment /> }
In this situation
Select.Fragment
is supposed to receivedata-v-*
prop but with the implementation above it won't.
Well it still doesn't because the plugin completely ignores any component name with dots in it