Skip to content

Commit ddb58dd

Browse files
yiminghezpao
authored andcommitted
consistent owner for stateless component (#6534)
(cherry picked from commit b11540c)
1 parent 7d9ded5 commit ddb58dd

File tree

3 files changed

+47
-6
lines changed

3 files changed

+47
-6
lines changed

src/renderers/shared/stack/reconciler/ReactCompositeComponent.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,12 +1093,17 @@ var ReactCompositeComponentMixin = {
10931093
*/
10941094
_renderValidatedComponent: function() {
10951095
var renderedComponent;
1096-
ReactCurrentOwner.current = this;
1097-
try {
1096+
if (__DEV__ || !(this._instance instanceof StatelessComponent)) {
1097+
ReactCurrentOwner.current = this;
1098+
try {
1099+
renderedComponent =
1100+
this._renderValidatedComponentWithoutOwnerOrContext();
1101+
} finally {
1102+
ReactCurrentOwner.current = null;
1103+
}
1104+
} else {
10981105
renderedComponent =
10991106
this._renderValidatedComponentWithoutOwnerOrContext();
1100-
} finally {
1101-
ReactCurrentOwner.current = null;
11021107
}
11031108
invariant(
11041109
// TODO: An `isValidNode` function would probably be more appropriate

src/renderers/shared/stack/reconciler/ReactRef.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ ReactRef.shouldUpdateRefs = function(prevElement, nextElement) {
6262
return (
6363
// This has a few false positives w/r/t empty components.
6464
prevEmpty || nextEmpty ||
65-
nextElement._owner !== prevElement._owner ||
66-
nextElement.ref !== prevElement.ref
65+
nextElement.ref !== prevElement.ref ||
66+
// If owner changes but we have an unchanged function ref, don't update refs
67+
(typeof nextElement.ref === 'string' &&
68+
nextElement._owner !== prevElement._owner)
6769
);
6870
};
6971

src/renderers/shared/stack/reconciler/__tests__/refs-test.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,4 +248,38 @@ describe('ref swapping', function() {
248248
var instance = ReactTestUtils.renderIntoDocument(<Component />);
249249
expect(!!instance.refs).toBe(true);
250250
});
251+
252+
function testRefCall() {
253+
var refCalled = 0;
254+
function Inner(props) {
255+
return <a ref={props.saveA} />;
256+
}
257+
var Outer = React.createClass({
258+
saveA() {
259+
refCalled++;
260+
},
261+
componentDidMount() {
262+
this.setState({});
263+
},
264+
render() {
265+
return <Inner saveA={this.saveA} />;
266+
},
267+
});
268+
ReactTestUtils.renderIntoDocument(<Outer />);
269+
expect(refCalled).toBe(1);
270+
}
271+
272+
it('ref called correctly for stateless component when __DEV__ = false', function() {
273+
var originalDev = __DEV__;
274+
__DEV__ = false;
275+
testRefCall();
276+
__DEV__ = originalDev;
277+
});
278+
279+
it('ref called correctly for stateless component when __DEV__ = true', function() {
280+
var originalDev = __DEV__;
281+
__DEV__ = true;
282+
testRefCall();
283+
__DEV__ = originalDev;
284+
});
251285
});

0 commit comments

Comments
 (0)