diff --git a/packages/babel-plugin-transform-es2015-destructuring/src/index.js b/packages/babel-plugin-transform-es2015-destructuring/src/index.js
index cad6e15b93..3fe8c9fd3b 100644
--- a/packages/babel-plugin-transform-es2015-destructuring/src/index.js
+++ b/packages/babel-plugin-transform-es2015-destructuring/src/index.js
@@ -496,12 +496,26 @@ export default function ({ types: t }) {
for (const node of nodes) {
const tail = nodesOut[nodesOut.length - 1];
if (tail && t.isVariableDeclaration(tail) && t.isVariableDeclaration(node) && tail.kind === node.kind) {
+ // Create a single compound let/var rather than many.
tail.declarations.push(...node.declarations);
} else {
nodesOut.push(node);
}
}
+ // Need to unmark the current binding to this var as a param, or other hoists
+ // could be placed above this ref.
+ // https://github.com/babel/babel/issues/4516
+ for (const nodeOut of nodesOut) {
+ if (!nodeOut.declarations) continue;
+ for (const declaration of nodeOut.declarations) {
+ const {name} = declaration.id;
+ if (scope.bindings[name]) {
+ scope.bindings[name].kind = nodeOut.kind;
+ }
+ }
+ }
+
if (nodesOut.length === 1) {
path.replaceWith(nodesOut[0]);
} else {
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/actual.js
new file mode 100644
index 0000000000..bbfb5d59e5
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/actual.js
@@ -0,0 +1,3 @@
+function render({ text, className, id }) {
+ return () => ();
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/expected.js
new file mode 100644
index 0000000000..c039c14143
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/expected.js
@@ -0,0 +1,9 @@
+function render(_ref) {
+ let text = _ref.text,
+ className = _ref.className,
+ id = _ref.id;
+
+ var _ref2 = ;
+
+ return () => _ref2;
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/options.json b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/options.json
new file mode 100644
index 0000000000..1d38616d70
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-multi/options.json
@@ -0,0 +1,4 @@
+{
+
+ "plugins": ["transform-es2015-destructuring", "transform-es2015-parameters", "transform-react-constant-elements", "syntax-jsx"]
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/actual.js
new file mode 100644
index 0000000000..aca4fea6a0
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/actual.js
@@ -0,0 +1,4 @@
+function render({ text, className, id, ...props }) {
+ // intentionally ignoring props
+ return () => ();
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/expected.js
new file mode 100644
index 0000000000..01bec851b2
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/expected.js
@@ -0,0 +1,13 @@
+function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
+function render(_ref) {
+ let text = _ref.text,
+ className = _ref.className,
+ id = _ref.id,
+ props = _objectWithoutProperties(_ref, ["text", "className", "id"]);
+
+ var _ref2 = ;
+
+ // intentionally ignoring props
+ return () => _ref2;
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/options.json b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/options.json
new file mode 100644
index 0000000000..100ca290b8
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-rest/options.json
@@ -0,0 +1,6 @@
+{
+
+ "plugins": ["transform-es2015-destructuring", "transform-es2015-parameters",
+ "transform-es2015-spread", "syntax-object-rest-spread",
+ "transform-react-constant-elements", "syntax-jsx"]
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/actual.js
new file mode 100644
index 0000000000..fbe2c61cea
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/actual.js
@@ -0,0 +1,3 @@
+function render({ text, className, id, ...props }) {
+ return () => ();
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/expected.js
new file mode 100644
index 0000000000..eb1d933b93
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/expected.js
@@ -0,0 +1,10 @@
+function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
+
+function render(_ref) {
+ let text = _ref.text,
+ className = _ref.className,
+ id = _ref.id,
+ props = _objectWithoutProperties(_ref, ["text", "className", "id"]);
+
+ return () => ;
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/options.json b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/options.json
new file mode 100644
index 0000000000..100ca290b8
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure-spread-deopt/options.json
@@ -0,0 +1,6 @@
+{
+
+ "plugins": ["transform-es2015-destructuring", "transform-es2015-parameters",
+ "transform-es2015-spread", "syntax-object-rest-spread",
+ "transform-react-constant-elements", "syntax-jsx"]
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/actual.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/actual.js
new file mode 100644
index 0000000000..a7fbd1c081
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/actual.js
@@ -0,0 +1,3 @@
+function render({ text }) {
+ return () => ();
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/expected.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/expected.js
new file mode 100644
index 0000000000..272a607c98
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/expected.js
@@ -0,0 +1,7 @@
+function render(_ref) {
+ let text = _ref.text;
+
+ var _ref2 = ;
+
+ return () => _ref2;
+}
diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/options.json b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/options.json
new file mode 100644
index 0000000000..1d38616d70
--- /dev/null
+++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/parameter-destructure/options.json
@@ -0,0 +1,4 @@
+{
+
+ "plugins": ["transform-es2015-destructuring", "transform-es2015-parameters", "transform-react-constant-elements", "syntax-jsx"]
+}