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) {