updateChildren: function( prevChildren, nextNestedChildNodes, transaction, context) { // We currently don't have a way to track moves here but if we use iterators // instead of for..in we can zip the iterators and check if an item has // moved. // TODO: If nothing has changed, return the prevChildren object so that we // can quickly bailout if nothing has changed. var nextChildren = flattenChildren(nextNestedChildNodes); if (!nextChildren && !prevChildren) { return null; } var name; for (name in nextChildren) { if (!nextChildren.hasOwnProperty(name)) { continue; } var prevChild = prevChildren && prevChildren[name]; var prevElement = prevChild && prevChild._currentElement; var nextElement = nextChildren[name]; if (shouldUpdateReactComponent(prevElement, nextElement)) { ReactReconciler.receiveComponent( prevChild, nextElement, transaction, context ); nextChildren[name] = prevChild; } else { if (prevChild) { ReactReconciler.unmountComponent(prevChild, name); } // The child must be instantiated before it's mounted. var nextChildInstance = instantiateReactComponent( nextElement, null ); nextChildren[name] = nextChildInstance; } } // Unmount children that are no longer present. for (name in prevChildren) { if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { ReactReconciler.unmountComponent(prevChildren[name]); } } return nextChildren; },
transaction.perform(function() { ReactReconciler.unmountComponent( component, false, /* safely */ false /* skipLifecycle */ ); });
_updateRenderedComponent: function(transaction, context) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; var nextRenderedElement = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { ReactReconciler.receiveComponent( prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context) ); } else { // These two IDs are actually the same! But nothing should rely on that. var thisID = this._rootNodeID; var prevComponentID = prevComponentInstance._rootNodeID; ReactReconciler.unmountComponent(prevComponentInstance); this._renderedComponent = this._instantiateReactComponent( nextRenderedElement, this._currentElement.type ); var nextMarkup = ReactReconciler.mountComponent( this._renderedComponent, thisID, transaction, this._processChildContext(context) ); this._replaceNodeWithMarkupByID(prevComponentID, nextMarkup); } },
_updateRenderedComponentWithNextElement: function( transaction, context, nextRenderedElement, safely, ) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; var debugID = 0; if (__DEV__) { debugID = this._debugID; } if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { ReactReconciler.receiveComponent( prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context), ); } else { var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance); var nodeType = ReactNodeTypes.getType(nextRenderedElement); this._renderedNodeType = nodeType; var child = this._instantiateReactComponent( nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */, ); this._renderedComponent = child; var nextMarkup = ReactReconciler.mountComponent( child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context), debugID, ); ReactReconciler.unmountComponent( prevComponentInstance, safely, false /* skipLifecycle */, ); if (__DEV__) { if (debugID !== 0) { var childDebugIDs = child._debugID !== 0 ? [child._debugID] : []; ReactInstrumentation.debugTool.onSetChildren(debugID, childDebugIDs); } } this._replaceNodeWithMarkup( oldHostNode, nextMarkup, prevComponentInstance, ); } },
_updateRenderedComponent: function(transaction, context) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; var nextRenderedElement = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { ReactReconciler.receiveComponent( prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context) ); } else { var oldNativeNode = ReactReconciler.unmountComponent(prevComponentInstance); this._renderedComponent = this._instantiateReactComponent( nextRenderedElement ); var nextMarkup = ReactReconciler.mountComponent( this._renderedComponent, this._rootNodeID, transaction, this._nativeParent, this._nativeContainerInfo, this._processChildContext(context) ); this._replaceNodeWithMarkup(oldNativeNode, nextMarkup); } },
unmountComponentFromNode: function( instance: ReactComponent, containerID: string ) { // Call back into native to remove all of the subviews from this container ReactReconciler.unmountComponent(instance); UIManager.removeSubviewsFromContainerWithID(containerID); },
unmountComponent: function(safely, skipLifecycle) { ReactReconciler.unmountComponent( this._renderedComponent, safely, skipLifecycle, ); this._renderedComponent = null; },
unmountChildren: function(renderedChildren, safely, skipLifecycle) { for (var name in renderedChildren) { if (renderedChildren.hasOwnProperty(name)) { var renderedChild = renderedChildren[name]; ReactReconciler.unmountComponent(renderedChild, safely, skipLifecycle); } } },
unmount() { if (this._instance) { ReactReconciler.unmountComponent( this._instance, false, /* safely */ false /* skipLifecycle */ ); } }
unmountComponentFromNode: function( instance: ReactComponent, containerID: string ) { // Call back into native to remove all of the subviews from this container ReactReconciler.unmountComponent(instance); var containerTag = ReactNativeTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID); RCTUIManager.removeSubviewsFromContainerWithID(containerTag); },
_updateRenderedComponent: function(transaction, context) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; var nextRenderedElement = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { ReactReconciler.receiveComponent( prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context) ); } else { var oldHostNode = ReactReconciler.getHostNode(prevComponentInstance); ReactReconciler.unmountComponent(prevComponentInstance, false); var nodeType = ReactNodeTypes.getType(nextRenderedElement); this._renderedNodeType = nodeType; var child = this._instantiateReactComponent( nextRenderedElement, nodeType !== ReactNodeTypes.EMPTY /* shouldHaveDebugID */ ); this._renderedComponent = child; if (__DEV__) { if (child._debugID !== 0 && this._debugID !== 0) { ReactInstrumentation.debugTool.onSetParent( child._debugID, this._debugID ); } } var nextMarkup = ReactReconciler.mountComponent( child, transaction, this._hostParent, this._hostContainerInfo, this._processChildContext(context) ); if (__DEV__) { if (this._debugID !== 0) { ReactInstrumentation.debugTool.onSetChildren( this._debugID, child._debugID !== 0 ? [child._debugID] : [] ); } } this._replaceNodeWithMarkup( oldHostNode, nextMarkup, prevComponentInstance ); } },
/** * 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, safely) { ReactReconciler.unmountComponent(instance, safely); if (container.nodeType === DOC_NODE_TYPE) { container = container.documentElement; } // http://jsperf.com/emptying-a-node while (container.lastChild) { container.removeChild(container.lastChild); } }
unmountComponent: function(safely) { if (!this._renderedComponent) { return; } var inst = this._instance; if (inst.componentWillUnmount) { if (safely) { var name = this.getName() + '.componentWillUnmount()'; ReactErrorUtils.invokeGuardedCallback(name, inst.componentWillUnmount.bind(inst)); } else { inst.componentWillUnmount(); } } if (this._renderedComponent) { ReactReconciler.unmountComponent(this._renderedComponent, safely); this._renderedNodeType = null; this._renderedComponent = null; this._instance = null; } // Reset pending fields // Even if this component is scheduled for another update in ReactUpdates, // it would still be ignored because these fields are reset. this._pendingStateQueue = null; this._pendingReplaceState = false; this._pendingForceUpdate = false; this._pendingCallbacks = null; this._pendingElement = null; // These fields do not really need to be reset since this object is no // longer accessible. this._context = null; this._rootNodeID = null; this._topLevelWrapper = null; // Delete the reference from the instance to this internal representation // which allow the internals to be properly cleaned up even if the user // leaks a reference to the public instance. ReactInstanceMap.remove(inst); // Some existing components rely on inst.props even after they've been // destroyed (in event handlers). // TODO: inst.props = null; // TODO: inst.state = null; // TODO: inst.context = null; },
/** * 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, safely) { if (__DEV__) { ReactInstrumentation.debugTool.onBeginFlush(); } ReactReconciler.unmountComponent(instance, safely); if (__DEV__) { ReactInstrumentation.debugTool.onEndFlush(); } if (container.nodeType === DOC_NODE_TYPE) { container = container.documentElement; } // http://jsperf.com/emptying-a-node while (container.lastChild) { container.removeChild(container.lastChild); } }
unmountComponent: function() { var inst = this._instance; if (inst.componentWillUnmount) { var previouslyUnmounting = ReactLifeCycle.currentlyUnmountingInstance; ReactLifeCycle.currentlyUnmountingInstance = this; try { inst.componentWillUnmount(); } finally { ReactLifeCycle.currentlyUnmountingInstance = previouslyUnmounting; } } ReactReconciler.unmountComponent(this._renderedComponent); this._renderedComponent = null; // Reset pending fields this._pendingStateQueue = null; this._pendingReplaceState = false; this._pendingForceUpdate = false; this._pendingCallbacks = null; this._pendingElement = null; // These fields do not really need to be reset since this object is no // longer accessible. this._context = null; this._rootNodeID = null; // Delete the reference from the instance to this internal representation // which allow the internals to be properly cleaned up even if the user // leaks a reference to the public instance. ReactInstanceMap.remove(inst); // Some existing components rely on inst.props even after they've been // destroyed (in event handlers). // TODO: inst.props = null; // TODO: inst.state = null; // TODO: inst.context = null; },
_updateRenderedComponent: function(transaction, context) { var prevComponentInstance = this._renderedComponent; var prevRenderedElement = prevComponentInstance._currentElement; var nextRenderedElement = this._renderValidatedComponent(); if (shouldUpdateReactComponent(prevRenderedElement, nextRenderedElement)) { ReactReconciler.receiveComponent( prevComponentInstance, nextRenderedElement, transaction, this._processChildContext(context) ); } else { // TODO: This is currently necessary due to the unfortunate caching // that ReactMount does which makes it exceedingly difficult to unmount // a set of siblings without accidentally repopulating the node cache (see // #5151). Once ReactMount no longer stores the nodes by ID, this method // can go away. var oldNativeNode = ReactReconciler.getNativeNode(prevComponentInstance); ReactReconciler.unmountComponent(prevComponentInstance); this._renderedNodeType = ReactNodeTypes.getType(nextRenderedElement); this._renderedComponent = this._instantiateReactComponent( nextRenderedElement ); var nextMarkup = ReactReconciler.mountComponent( this._renderedComponent, this._rootNodeID, transaction, this._nativeParent, this._nativeContainerInfo, this._processChildContext(context) ); this._replaceNodeWithMarkup(oldNativeNode, nextMarkup); } },
ReactShallowRenderer.prototype.unmount = function() { if (this._instance) { ReactReconciler.unmountComponent(this._instance, false); } };
unmountComponent: function() { ReactReconciler.unmountComponent(this._renderedComponent); this._renderedComponent = null; },
unmountChildren: function(renderedChildren) { for (var name in renderedChildren) { var renderedChild = renderedChildren[name]; ReactReconciler.unmountComponent(renderedChild); } }
unmountComponent: function(rootID, transaction, context) { ReactReconciler.unmountComponent(this._renderedComponent); this._rootNodeID = null; this._renderedComponent = null; },
updateChildren: function( prevChildren, nextChildren, mountImages, removedNodes, transaction, hostParent, hostContainerInfo, context, selfDebugID // 0 in production and for roots ) { // We currently don't have a way to track moves here but if we use iterators // instead of for..in we can zip the iterators and check if an item has // moved. // TODO: If nothing has changed, return the prevChildren object so that we // can quickly bailout if nothing has changed. if (!nextChildren && !prevChildren) { return; } var name; var prevChild; for (name in nextChildren) { if (!nextChildren.hasOwnProperty(name)) { continue; } prevChild = prevChildren && prevChildren[name]; var prevElement = prevChild && prevChild._currentElement; var nextElement = nextChildren[name]; if (prevChild != null && shouldUpdateReactComponent(prevElement, nextElement)) { ReactReconciler.receiveComponent( prevChild, nextElement, transaction, context ); nextChildren[name] = prevChild; } else { if ( !ReactFeatureFlags.prepareNewChildrenBeforeUnmountInStack && prevChild ) { removedNodes[name] = ReactReconciler.getHostNode(prevChild); ReactReconciler.unmountComponent( prevChild, false, /* safely */ false /* skipLifecycle */ ); } // The child must be instantiated before it's mounted. var nextChildInstance = instantiateReactComponent(nextElement, true); nextChildren[name] = nextChildInstance; // Creating mount image now ensures refs are resolved in right order // (see https://github.com/facebook/react/pull/7101 for explanation). var nextChildMountImage = ReactReconciler.mountComponent( nextChildInstance, transaction, hostParent, hostContainerInfo, context, selfDebugID ); mountImages.push(nextChildMountImage); if ( ReactFeatureFlags.prepareNewChildrenBeforeUnmountInStack && prevChild ) { removedNodes[name] = ReactReconciler.getHostNode(prevChild); ReactReconciler.unmountComponent( prevChild, false, /* safely */ false /* skipLifecycle */ ); } } } // Unmount children that are no longer present. for (name in prevChildren) { if (prevChildren.hasOwnProperty(name) && !(nextChildren && nextChildren.hasOwnProperty(name))) { prevChild = prevChildren[name]; removedNodes[name] = ReactReconciler.getHostNode(prevChild); ReactReconciler.unmountComponent( prevChild, false, /* safely */ false /* skipLifecycle */ ); } } },