mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
fix instance null when involve async destruction
This commit is contained in:
@@ -95,9 +95,10 @@ var ReactOwner = {
|
||||
'`render` method, or you have multiple copies of React loaded ' +
|
||||
'(details: https://fb.me/react-refs-must-have-owner).'
|
||||
);
|
||||
// Check that `component` is still the current ref because we do not want to
|
||||
// detach the ref if another component stole it.
|
||||
if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) {
|
||||
var ownerPublicInstance = owner.getPublicInstance();
|
||||
// Check that `component`'s owner is still alive and that `component` is still the current ref
|
||||
// because we do not want to detach the ref if another component stole it.
|
||||
if (ownerPublicInstance && ownerPublicInstance.refs[ref] === component.getPublicInstance()) {
|
||||
owner.detachRef(ref);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -59,4 +59,46 @@ describe('refs-destruction', function() {
|
||||
ReactDOM.render(<TestComponent destroy={true} />, container);
|
||||
expect(Object.keys(testInstance.refs || {}).length).toEqual(0);
|
||||
});
|
||||
|
||||
it('should not error when destroying child with ref asynchronously', function() {
|
||||
var Modal = React.createClass({
|
||||
componentDidMount: function() {
|
||||
this.div = document.createElement('div');
|
||||
document.body.appendChild(this.div);
|
||||
this.componentDidUpdate();
|
||||
},
|
||||
componentDidUpdate: function() {
|
||||
ReactDOM.render(<div>{this.props.children}</div>, this.div);
|
||||
},
|
||||
componentWillUnmount: function() {
|
||||
var self = this;
|
||||
// some async animation
|
||||
setTimeout(function() {
|
||||
expect(function() {
|
||||
ReactDOM.unmountComponentAtNode(self.div);
|
||||
}).not.toThrow();
|
||||
document.body.removeChild(self.div);
|
||||
}, 0);
|
||||
},
|
||||
render() {
|
||||
return null;
|
||||
},
|
||||
});
|
||||
var AppModal = React.createClass({
|
||||
render: function() {
|
||||
return (<Modal>
|
||||
<a ref="ref"/>
|
||||
</Modal>);
|
||||
},
|
||||
});
|
||||
var App = React.createClass({
|
||||
render: function() {
|
||||
return this.props.hidden ? null : <AppModal onClose={this.close}/>;
|
||||
},
|
||||
});
|
||||
var container = document.createElement('div');
|
||||
ReactDOM.render(<App />, container);
|
||||
ReactDOM.render(<App hidden={true}/>, container);
|
||||
jest.runAllTimers();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user