Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| /** | |
| * Copyright 2013-present, Facebook, Inc. | |
| * All rights reserved. | |
| * | |
| * This source code is licensed under the BSD-style license found in the | |
| * LICENSE file in the root directory of this source tree. An additional grant | |
| * of patent rights can be found in the PATENTS file in the same directory. | |
| * | |
| * @providesModule ReactReconciler | |
| */ | |
| 'use strict'; | |
| var ReactRef = require('ReactRef'); | |
| var ReactInstrumentation = require('ReactInstrumentation'); | |
| var warning = require('warning'); | |
| /** | |
| * Helper to call ReactRef.attachRefs with this composite component, split out | |
| * to avoid allocations in the transaction mount-ready queue. | |
| */ | |
| function attachRefs(transaction) { | |
| ReactRef.attachRefs( | |
| this, | |
| this._currentElement, | |
| transaction, | |
| ); | |
| } | |
| var ReactReconciler = { | |
| /** | |
| * Initializes the component, renders markup, and registers event listeners. | |
| * | |
| * @param {ReactComponent} internalInstance | |
| * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction | |
| * @param {?object} the containing host component instance | |
| * @param {?object} info about the host container | |
| * @return {?string} Rendered markup to be inserted into the DOM. | |
| * @final | |
| * @internal | |
| */ | |
| mountComponent: function( | |
| internalInstance, | |
| transaction, | |
| hostParent, | |
| hostContainerInfo, | |
| context, | |
| parentDebugID // 0 in production and for roots | |
| ) { | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onBeforeMountComponent( | |
| internalInstance._debugID, | |
| internalInstance._currentElement, | |
| parentDebugID | |
| ); | |
| } | |
| } | |
| var markup = internalInstance.mountComponent( | |
| transaction, | |
| hostParent, | |
| hostContainerInfo, | |
| context, | |
| parentDebugID | |
| ); | |
| if (internalInstance._currentElement && | |
| internalInstance._currentElement.ref != null) { | |
| transaction.getReactMountReady().enqueue(attachRefs, internalInstance); | |
| } | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onMountComponent( | |
| internalInstance._debugID | |
| ); | |
| } | |
| } | |
| return markup; | |
| }, | |
| /** | |
| * Returns a value that can be passed to | |
| * ReactComponentEnvironment.replaceNodeWithMarkup. | |
| */ | |
| getHostNode: function(internalInstance) { | |
| return internalInstance.getHostNode(); | |
| }, | |
| /** | |
| * Releases any resources allocated by `mountComponent`. | |
| * | |
| * @final | |
| * @internal | |
| */ | |
| unmountComponent: function(internalInstance, safely) { | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onBeforeUnmountComponent( | |
| internalInstance._debugID | |
| ); | |
| } | |
| } | |
| ReactRef.detachRefs(internalInstance, internalInstance._currentElement); | |
| internalInstance.unmountComponent(safely); | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onUnmountComponent( | |
| internalInstance._debugID | |
| ); | |
| } | |
| } | |
| }, | |
| /** | |
| * Update a component using a new element. | |
| * | |
| * @param {ReactComponent} internalInstance | |
| * @param {ReactElement} nextElement | |
| * @param {ReactReconcileTransaction} transaction | |
| * @param {object} context | |
| * @internal | |
| */ | |
| receiveComponent: function( | |
| internalInstance, nextElement, transaction, context | |
| ) { | |
| var prevElement = internalInstance._currentElement; | |
| if (nextElement === prevElement && | |
| context === internalInstance._context | |
| ) { | |
| // Since elements are immutable after the owner is rendered, | |
| // we can do a cheap identity compare here to determine if this is a | |
| // superfluous reconcile. It's possible for state to be mutable but such | |
| // change should trigger an update of the owner which would recreate | |
| // the element. We explicitly check for the existence of an owner since | |
| // it's possible for an element created outside a composite to be | |
| // deeply mutated and reused. | |
| // TODO: Bailing out early is just a perf optimization right? | |
| // TODO: Removing the return statement should affect correctness? | |
| return; | |
| } | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onBeforeUpdateComponent( | |
| internalInstance._debugID, | |
| nextElement | |
| ); | |
| } | |
| } | |
| var refsChanged = ReactRef.shouldUpdateRefs( | |
| prevElement, | |
| nextElement | |
| ); | |
| if (refsChanged) { | |
| ReactRef.detachRefs(internalInstance, prevElement); | |
| } | |
| internalInstance.receiveComponent(nextElement, transaction, context); | |
| if (refsChanged && | |
| internalInstance._currentElement && | |
| internalInstance._currentElement.ref != null) { | |
| transaction.getReactMountReady().enqueue(attachRefs, internalInstance); | |
| } | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onUpdateComponent( | |
| internalInstance._debugID | |
| ); | |
| } | |
| } | |
| }, | |
| /** | |
| * Flush any dirty changes in a component. | |
| * | |
| * @param {ReactComponent} internalInstance | |
| * @param {ReactReconcileTransaction} transaction | |
| * @internal | |
| */ | |
| performUpdateIfNecessary: function( | |
| internalInstance, | |
| transaction, | |
| updateBatchNumber | |
| ) { | |
| if (internalInstance._updateBatchNumber !== updateBatchNumber) { | |
| // The component's enqueued batch number should always be the current | |
| // batch or the following one. | |
| warning( | |
| internalInstance._updateBatchNumber == null || | |
| internalInstance._updateBatchNumber === updateBatchNumber + 1, | |
| 'performUpdateIfNecessary: Unexpected batch number (current %s, ' + | |
| 'pending %s)', | |
| updateBatchNumber, | |
| internalInstance._updateBatchNumber | |
| ); | |
| return; | |
| } | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onBeforeUpdateComponent( | |
| internalInstance._debugID, | |
| internalInstance._currentElement | |
| ); | |
| } | |
| } | |
| internalInstance.performUpdateIfNecessary(transaction); | |
| if (__DEV__) { | |
| if (internalInstance._debugID !== 0) { | |
| ReactInstrumentation.debugTool.onUpdateComponent( | |
| internalInstance._debugID | |
| ); | |
| } | |
| } | |
| }, | |
| }; | |
| module.exports = ReactReconciler; |