diff --git a/src/proxy/inject.js b/src/proxy/inject.js index 94ad20957..834a97edb 100644 --- a/src/proxy/inject.js +++ b/src/proxy/inject.js @@ -81,12 +81,13 @@ function mergeComponents( const nextString = String(nextAttr) const injectedBefore = injectedMembers[key] - const isFunction = - nextString.indexOf('function') >= 0 || nextString.indexOf('=>') >= 0 + const isArrow = nextString.indexOf('=>') >= 0 + const isFunction = nextString.indexOf('function') >= 0 || isArrow + const referToThis = nextString.indexOf('this') >= 0 if ( nextString !== String(prevAttr) || (injectedBefore && nextString !== String(injectedBefore)) || - isFunction + (isArrow && referToThis) ) { if (!hasRegenerate) { if (!isFunction) { @@ -150,15 +151,13 @@ function inject(target, currentGeneration, injectedMembers) { Object.keys(injectedMembers).forEach(key => { try { if (hasRegenerate) { + const usedThis = + String(injectedMembers[key]).match(/_this([\d])/gi) || [] target[REGENERATE_METHOD]( key, `(function REACT_HOT_LOADER_SANDBOX () { - var _this = this; // common babel transpile - var _this2 = this; // common babel transpile - var _this3 = this; // common babel transpile - var _this4 = this; // common babel transpile - var _this5 = this; // common babel transpile - var _this6 = this; // common babel transpile + ${usedThis.map(name => `var ${name} = this;`)} + return ${injectedMembers[key]}; }).call(this)`, ) diff --git a/test/proxy/consistency.test.js b/test/proxy/consistency.test.js index bc6b90b43..c2ee3484e 100644 --- a/test/proxy/consistency.test.js +++ b/test/proxy/consistency.test.js @@ -268,14 +268,35 @@ describe('consistency', () => { /* eslint-enable */ }) - it('should reflect external dependencies', () => { + it('should reflect external dependencies(broken, regression)', () => { /* eslint-disable */ const externalValue = 42 + let gen = 0 + const generator2 = () => { + const g = gen++ + return () => g + } + const generator3 = () => { + const g = gen++ + return () => g + } class BaseClass extends React.Component { - arrow = () => externalValue + secret1 = 1 + secret2 = generator2() + secret3 = generator3() + arrow1 = () => externalValue + arrow2 = () => this.secret1 + externalValue render() { - return this.arrow() + return ( + this.arrow1() + + ':' + + this.arrow2() + + ':' + + this.secret2() + + ':' + + this.secret3() + ) } __reactstandin__regenerateByEval(key, code) { @@ -286,15 +307,27 @@ describe('consistency', () => { const proxy = createProxy(BaseClass) const Proxy = proxy.get() const instance = new Proxy() - expect(instance.render()).toBe(42) + expect(instance.render()).toBe(42 + ':' + 43 + ':' + 0 + ':' + 1) { const externalValue = 24 class Update1Class extends React.Component { - arrow = () => externalValue + secret = 1 + secret2 = generator2() + secret3 = generator3() + arrow1 = () => externalValue + arrow2 = () => this.secret1 + externalValue render() { - return this.arrow() + return ( + this.arrow1() + + ':' + + this.arrow2() + + ':' + + this.secret2() + + ':' + + this.secret3() + ) } __reactstandin__regenerateByEval(key, code) { @@ -306,7 +339,13 @@ describe('consistency', () => { } /* eslint-enable */ - expect(instance.render()).toBe(24) + // Arrow1 function refer to external variable + // Will not be updated + // while Arrow2 function will + + // secret 3 should not be regenrated + // secret 4(this inside) should be regenrated + expect(instance.render()).toMatch(/([\d]+):25:0:1/) }) it('should stand-for all class members', () => {