Merge remote-tracking branch 'spicyj/depth-not-owner'

This commit is contained in:
Paul O’Shannessy 2013-12-05 15:51:39 -08:00
commit 7db8f818bc
2 changed files with 56 additions and 8 deletions

View File

@ -260,17 +260,17 @@ var ReactComponent = {
*/
replaceProps: function(props, callback) {
invariant(
!this._owner,
this.isMounted(),
'replaceProps(...): Can only update a mounted component.'
);
invariant(
this._mountDepth === 0,
'replaceProps(...): You called `setProps` or `replaceProps` on a ' +
'component with an owner. This is an anti-pattern since props will ' +
'component with a parent. This is an anti-pattern since props will ' +
'get reactively updated when rendered. Instead, change the owner\'s ' +
'`render` method to pass the correct value as props to the component ' +
'where it is created.'
);
invariant(
this.isMounted(),
'replaceProps(...): Can only update a mounted component.'
);
this._pendingProps = props;
ReactUpdates.enqueueUpdate(this, callback);
},

View File

@ -404,8 +404,56 @@ describe('ReactComponentLifeCycle', function() {
valueToUseInitially="hello"
valueToUseInOnDOMReady="goodbye"
/>;
expect(ReactTestUtils.renderIntoDocument.bind(ReactTestUtils, instance))
.toThrow();
expect(function() {
ReactTestUtils.renderIntoDocument(instance)
}).toThrow(
'Invariant Violation: replaceProps(...): You called `setProps` or ' +
'`replaceProps` on a component with a parent. This is an anti-pattern ' +
'since props will get reactively updated when rendered. Instead, ' +
'change the owner\'s `render` method to pass the correct value as ' +
'props to the component where it is created.'
);
});
it('should not throw when updating an auxiliary component', function() {
var Tooltip = React.createClass({
render: function() {
return <div>{this.props.children}</div>;
},
componentDidMount: function() {
this.container = document.createElement('div');
this.updateTooltip();
},
componentDidUpdate: function() {
this.updateTooltip();
},
updateTooltip: function() {
// Even though this.props.tooltip has an owner, updating it shouldn't
// throw here because it's mounted as a root component
React.renderComponent(this.props.tooltip, this.container);
}
});
var Component = React.createClass({
render: function() {
return (
<Tooltip
ref="tooltip"
tooltip={<div>{this.props.tooltipText}</div>}>
{this.props.text}
</Tooltip>
);
}
});
var container = document.createElement('div');
var instance = React.renderComponent(
<Component text="uno" tooltipText="one" />,
container
);
// Since `instance` is a root component, we can set its props. This also
// makes Tooltip rerender the tooltip component, which shouldn't throw.
instance.setProps({text: "dos", tooltipText: "two"});
});
it('should throw when calling setProps() on an unmounted component',