diff --git a/packages/babel-plugin-transform-react-constant-elements/src/index.js b/packages/babel-plugin-transform-react-constant-elements/src/index.js index 2e486772bd..873b15a4d4 100644 --- a/packages/babel-plugin-transform-react-constant-elements/src/index.js +++ b/packages/babel-plugin-transform-react-constant-elements/src/index.js @@ -64,13 +64,17 @@ export default declare((api, options) => { // Ignore identifiers & JSX expressions. if ( path.isJSXIdentifier() || - path.isIdentifier() || path.isJSXMemberExpression() || path.isJSXNamespacedName() ) { return; } + if (path.isIdentifier()) { + const binding = path.scope.getBinding(path.node.name); + if (binding && binding.constant) return; + } + if (!path.isImmutable()) { // If it's not immutable, it may still be a pure expression, such as string concatenation. // It is still safe to hoist that, so long as its result is immutable. diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs index a4e8fa17c0..83c8f67722 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable-complex/output.mjs @@ -1,5 +1,3 @@ -var _span; - let foo = 'hello'; const mutate = () => { @@ -8,5 +6,5 @@ const mutate = () => { export const Component = () => { if (Math.random() > 0.5) mutate(); - return _span || (_span = {foo}); + return {foo}; }; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs index 15241789ce..dd266a198d 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/deopt-mutable/output.mjs @@ -1,7 +1,5 @@ -var _span; - let foo = 'hello'; export const Component = () => { foo = 'goodbye'; - return _span || (_span = {foo}); + return {foo}; }; diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js new file mode 100644 index 0000000000..1dcb56c032 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/input.js @@ -0,0 +1,10 @@ +function render() { + const nodes = []; + + for(let i = 0; i < 5; i++) { + nodes.push(
{i}
) + } + + return nodes; +} + \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js new file mode 100644 index 0000000000..af1cee1ef5 --- /dev/null +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/for-loop/output.js @@ -0,0 +1,10 @@ +function render() { + const nodes = []; + + for (let i = 0; i < 5; i++) { + nodes.push(
{i}
); + } + + return nodes; +} + \ No newline at end of file diff --git a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js index e7d32f1d64..dbaf45c6d7 100644 --- a/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js +++ b/packages/babel-plugin-transform-react-constant-elements/test/fixtures/constant-elements/global-reference/output.js @@ -1,7 +1,5 @@ -var _div; - var Foo = React.createClass({ render: function render() { - return _div || (_div =
); + return
; } });