From b11540ccb2321aeb7259fcf0b3a38aeeea35231d Mon Sep 17 00:00:00 2001 From: yiminghe Date: Mon, 18 Apr 2016 16:08:13 +0800 Subject: [PATCH] consistent owner for stateless component (#6534) --- .../reconciler/ReactCompositeComponent.js | 13 ++++--- .../shared/stack/reconciler/ReactRef.js | 6 ++-- .../stack/reconciler/__tests__/refs-test.js | 34 +++++++++++++++++++ 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js index 37d91f1be0917..b07948f0a79f6 100644 --- a/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js +++ b/src/renderers/shared/stack/reconciler/ReactCompositeComponent.js @@ -1117,12 +1117,17 @@ var ReactCompositeComponentMixin = { */ _renderValidatedComponent: function() { var renderedComponent; - ReactCurrentOwner.current = this; - try { + if (__DEV__ || !(this._instance instanceof StatelessComponent)) { + ReactCurrentOwner.current = this; + try { + renderedComponent = + this._renderValidatedComponentWithoutOwnerOrContext(); + } finally { + ReactCurrentOwner.current = null; + } + } else { renderedComponent = this._renderValidatedComponentWithoutOwnerOrContext(); - } finally { - ReactCurrentOwner.current = null; } invariant( // TODO: An `isValidNode` function would probably be more appropriate diff --git a/src/renderers/shared/stack/reconciler/ReactRef.js b/src/renderers/shared/stack/reconciler/ReactRef.js index 3ddc23fbd6c22..a33ca13f1c09e 100644 --- a/src/renderers/shared/stack/reconciler/ReactRef.js +++ b/src/renderers/shared/stack/reconciler/ReactRef.js @@ -62,8 +62,10 @@ ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { return ( // This has a few false positives w/r/t empty components. prevEmpty || nextEmpty || - nextElement._owner !== prevElement._owner || - nextElement.ref !== prevElement.ref + nextElement.ref !== prevElement.ref || + // If owner changes but we have an unchanged function ref, don't update refs + (typeof nextElement.ref === 'string' && + nextElement._owner !== prevElement._owner) ); }; diff --git a/src/renderers/shared/stack/reconciler/__tests__/refs-test.js b/src/renderers/shared/stack/reconciler/__tests__/refs-test.js index 8e2733258a6ca..6811cfe4dc316 100644 --- a/src/renderers/shared/stack/reconciler/__tests__/refs-test.js +++ b/src/renderers/shared/stack/reconciler/__tests__/refs-test.js @@ -240,5 +240,39 @@ describe('ref swapping', function() { var instance = ReactTestUtils.renderIntoDocument(); expect(!!instance.refs).toBe(true); }); + + function testRefCall() { + var refCalled = 0; + function Inner(props) { + return ; + } + var Outer = React.createClass({ + saveA() { + refCalled++; + }, + componentDidMount() { + this.setState({}); + }, + render() { + return ; + }, + }); + ReactTestUtils.renderIntoDocument(); + expect(refCalled).toBe(1); + } + + it('ref called correctly for stateless component when __DEV__ = false', function() { + var originalDev = __DEV__; + __DEV__ = false; + testRefCall(); + __DEV__ = originalDev; + }); + + it('ref called correctly for stateless component when __DEV__ = true', function() { + var originalDev = __DEV__; + __DEV__ = true; + testRefCall(); + __DEV__ = originalDev; + }); });