Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up
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; |