@samitouri / QOS-React-2 / commits / e7704e22a1

[babel-plugin-react-jsx] Avoid duplicate "children" key in props object (#17094)

* [babel-plugin-react-jsx] Avoid duplicate "children" key in props object * Use Object.assign approach

Dominic Gannaway committed Oct 15, 2019 at 15:41 UTC e7704e22a146c2d5b00f8c6bfa6255153272f053
3 files changed +32 -1
packages/babel-plugin-react-jsx/__tests__/TransformJSXToReactJSX-test.js
+6
@@ -480,4 +480,10 @@ describe('transform react to jsx', () => {
480 transform(`<Component y={2} {...x} />`, {useBuiltIns: false})
481 ).toMatchSnapshot();
482 });
483 +
484 + it('should not contain duplicate children key in props object', () => {
485 + expect(
486 + transform(`<Component children={1}>2</Component>`)
487 + ).toMatchSnapshot();
488 + });
489 });
packages/babel-plugin-react-jsx/__tests__/__snapshots__/TransformJSXToReactJSX-test.js.snap
+8
@@ -250,6 +250,14 @@ var e = React.jsx(F, {
250 });
251 `;
252
253 +exports[`transform react to jsx should not contain duplicate children key in props object 1`] = `
254 +React.jsx(Component, Object.assign({
255 + children: 1
256 +}, {
257 + children: "2"
258 +}));
259 +`;
260 +
261 exports[`transform react to jsx should not strip nbsp even couple with other whitespace 1`] = `
262 React.jsx("div", {
263 children: "\\xA0 "
packages/babel-plugin-react-jsx/src/TransformJSXToReactBabelPlugin.js
+18 -1
@@ -268,11 +268,20 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
268 );
269 }
270
271 + function isChildrenProp(prop) {
272 + return (
273 + t.isJSXAttribute(prop) &&
274 + t.isJSXIdentifier(prop.name) &&
275 + prop.name.name === 'children'
276 + );
277 + }
278 +
279 // Builds props for React.jsx. This function adds children into the props
280 // and ensures that props is always an object
281 function buildJSXOpeningElementAttributes(attribs, file, children) {
282 let _props = [];
283 const objs = [];
284 + const hasChildren = children && children.length > 0;
285
286 const useBuiltIns = file.opts.useBuiltIns || false;
287 if (typeof useBuiltIns !== 'boolean') {
@@ -287,6 +296,14 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
296 if (t.isJSXSpreadAttribute(prop)) {
297 _props = pushProps(_props, objs);
298 objs.push(prop.argument);
299 + } else if (hasChildren && isChildrenProp(prop)) {
300 + // In order to avoid having duplicate "children" keys, we avoid
301 + // pushing the "children" prop if we have actual children. Instead
302 + // we put the children into a separate object and then rely on
303 + // the Object.assign logic below to ensure the correct object is
304 + // formed.
305 + _props = pushProps(_props, objs);
306 + objs.push(t.objectExpression([convertAttribute(prop)]));
307 } else {
308 _props.push(convertAttribute(prop));
309 }
@@ -294,7 +311,7 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
311
312 // In React.JSX, children is no longer a separate argument, but passed in
313 // through the argument object
297 - if (children && children.length > 0) {
314 + if (hasChildren) {
315 if (children.length === 1) {
316 _props.push(t.objectProperty(t.identifier('children'), children[0]));
317 } else {