mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Merge pull request #3795 from spicyj/batch-unmount
Batch updates within top-level unmount
This commit is contained in:
@@ -306,6 +306,28 @@ function batchedMountComponentIntoNode(
|
|||||||
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmounts a component and removes it from the DOM.
|
||||||
|
*
|
||||||
|
* @param {ReactComponent} instance React component instance.
|
||||||
|
* @param {DOMElement} container DOM element to unmount from.
|
||||||
|
* @final
|
||||||
|
* @internal
|
||||||
|
* @see {ReactMount.unmountComponentAtNode}
|
||||||
|
*/
|
||||||
|
function unmountComponentFromNode(instance, container) {
|
||||||
|
ReactReconciler.unmountComponent(instance);
|
||||||
|
|
||||||
|
if (container.nodeType === DOC_NODE_TYPE) {
|
||||||
|
container = container.documentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://jsperf.com/emptying-a-node
|
||||||
|
while (container.lastChild) {
|
||||||
|
container.removeChild(container.lastChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mounting is the process of initializing a React component by creating its
|
* Mounting is the process of initializing a React component by creating its
|
||||||
* representative DOM elements and inserting them into a supplied `container`.
|
* representative DOM elements and inserting them into a supplied `container`.
|
||||||
@@ -668,7 +690,11 @@ var ReactMount = {
|
|||||||
if (!component) {
|
if (!component) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ReactMount.unmountComponentFromNode(component, container);
|
ReactUpdates.batchedUpdates(
|
||||||
|
unmountComponentFromNode,
|
||||||
|
component,
|
||||||
|
container
|
||||||
|
);
|
||||||
delete instancesByReactRootID[reactRootID];
|
delete instancesByReactRootID[reactRootID];
|
||||||
delete containersByReactRootID[reactRootID];
|
delete containersByReactRootID[reactRootID];
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
@@ -677,28 +703,6 @@ var ReactMount = {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Unmounts a component and removes it from the DOM.
|
|
||||||
*
|
|
||||||
* @param {ReactComponent} instance React component instance.
|
|
||||||
* @param {DOMElement} container DOM element to unmount from.
|
|
||||||
* @final
|
|
||||||
* @internal
|
|
||||||
* @see {ReactMount.unmountComponentAtNode}
|
|
||||||
*/
|
|
||||||
unmountComponentFromNode: function(instance, container) {
|
|
||||||
ReactReconciler.unmountComponent(instance);
|
|
||||||
|
|
||||||
if (container.nodeType === DOC_NODE_TYPE) {
|
|
||||||
container = container.documentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://jsperf.com/emptying-a-node
|
|
||||||
while (container.lastChild) {
|
|
||||||
container.removeChild(container.lastChild);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the container DOM element that contains React component to which the
|
* Finds the container DOM element that contains React component to which the
|
||||||
* supplied DOM `id` belongs.
|
* supplied DOM `id` belongs.
|
||||||
|
|||||||
@@ -218,4 +218,32 @@ describe('ReactCompositeComponent-state', function() {
|
|||||||
['componentWillUnmount', 'blue']
|
['componentWillUnmount', 'blue']
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should batch unmounts', function() {
|
||||||
|
var outer;
|
||||||
|
var Inner = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
return <div />;
|
||||||
|
},
|
||||||
|
componentWillUnmount: function() {
|
||||||
|
// This should get silently ignored (maybe with a warning), but it
|
||||||
|
// shouldn't break React.
|
||||||
|
outer.setState({showInner: false});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var Outer = React.createClass({
|
||||||
|
getInitialState: function() {
|
||||||
|
return {showInner: true};
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
return <div>{this.state.showInner && <Inner />}</div>;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var container = document.createElement('div');
|
||||||
|
outer = React.render(<Outer />, container);
|
||||||
|
expect(() => {
|
||||||
|
React.unmountComponentAtNode(container);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user