diff --git a/packages/babel-plugin-react-jsx/src/TransformJSXToReactBabelPlugin.js b/packages/babel-plugin-react-jsx/src/TransformJSXToReactBabelPlugin.js index 58296ef4ca02..308fc7116f8c 100644 --- a/packages/babel-plugin-react-jsx/src/TransformJSXToReactBabelPlugin.js +++ b/packages/babel-plugin-react-jsx/src/TransformJSXToReactBabelPlugin.js @@ -284,6 +284,17 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`, function buildJSXOpeningElementAttributes(attribs, file, children) { let _props = []; const objs = []; + + // In order to avoid having duplicate "children" keys, we avoid + // pushing the "children" prop if we have actual children. However, + // the children prop may have side effects, so to be certain + // these side effects are evaluated, we add them to the following prop + // as a sequence expression to preserve order. So: + //
{child}
becomes + // React.jsx('div', {foo: (x++, y), children: child}); + // duplicateChildren contains the extra children prop values + let duplicateChildren = []; + const hasChildren = children && children.length > 0; const useBuiltIns = file.opts.useBuiltIns || false; @@ -294,10 +305,11 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`, ); } - let duplicateChildren = []; while (attribs.length) { const prop = attribs.shift(); - if (t.isJSXSpreadAttribute(prop)) { + if (hasChildren && isChildrenProp(prop)) { + duplicateChildren.push(convertAttributeValue(prop.value)); + } else if (t.isJSXSpreadAttribute(prop)) { _props = pushProps(_props, objs); if (duplicateChildren.length > 0) { objs.push( @@ -307,13 +319,6 @@ You can turn on the 'throwIfNamespace' flag to bypass this warning.`, } else { objs.push(prop.argument); } - } else if (hasChildren && isChildrenProp(prop)) { - // In order to avoid having duplicate "children" keys, we avoid - // pushing the "children" prop if we have actual children. Instead - // we put the children into a separate object and then rely on - // the Object.assign logic below to ensure the correct object is - // formed. - duplicateChildren.push(convertAttributeValue(prop.value)); } else { _props.push(convertAttribute(prop, duplicateChildren)); if (duplicateChildren.length > 0) {