Skip to content

Commit

Permalink
Walk down internal tree to find DOM node
Browse files Browse the repository at this point in the history
This reduces our reliance on hierarchical IDs. If facebook#4983 merges, this can look at `._nativeNode` when present.
  • Loading branch information
sophiebits committed Sep 28, 2015
1 parent b82f3ab commit a39217a
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 85 deletions.
22 changes: 0 additions & 22 deletions src/renderers/dom/client/ReactMount.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter');
var ReactCurrentOwner = require('ReactCurrentOwner');
var ReactDOMFeatureFlags = require('ReactDOMFeatureFlags');
var ReactElement = require('ReactElement');
var ReactEmptyComponentRegistry = require('ReactEmptyComponentRegistry');
var ReactInstanceHandles = require('ReactInstanceHandles');
var ReactInstanceMap = require('ReactInstanceMap');
var ReactMarkupChecksum = require('ReactMarkupChecksum');
var ReactPerf = require('ReactPerf');
var ReactReconciler = require('ReactReconciler');
Expand Down Expand Up @@ -170,24 +168,6 @@ function getNode(id) {
return nodeCache[id];
}

/**
* Finds the node with the supplied public React instance.
*
* @param {*} instance A public React instance.
* @return {?DOMElement} DOM node with the suppled `id`.
* @internal
*/
function getNodeFromInstance(instance) {
var id = ReactInstanceMap.get(instance)._rootNodeID;
if (ReactEmptyComponentRegistry.isNullComponentID(id)) {
return null;
}
if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) {
nodeCache[id] = ReactMount.findReactNodeByID(id);
}
return nodeCache[id];
}

/**
* A node is "valid" if it is contained by a currently mounted container.
*
Expand Down Expand Up @@ -1082,8 +1062,6 @@ var ReactMount = {

getNode: getNode,

getNodeFromInstance: getNodeFromInstance,

isValid: isValid,

purgeID: purgeID,
Expand Down
48 changes: 36 additions & 12 deletions src/renderers/dom/client/findDOMNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,22 @@ var ReactMount = require('ReactMount');
var invariant = require('invariant');
var warning = require('warning');

function getNativeComponentFromComposite(inst) {
var renderedElement;

do {
renderedElement = inst._renderedElement;
if (typeof renderedElement === 'object' && renderedElement != null) {
inst = inst._renderedComponent;
} else {
// Empty or text component
return null;
}
} while (typeof renderedElement.type === 'function');

return inst;
}

/**
* Returns the DOM node rendered by this element.
*
Expand Down Expand Up @@ -47,19 +63,27 @@ function findDOMNode(componentOrElement) {
if (componentOrElement.nodeType === 1) {
return componentOrElement;
}
if (ReactInstanceMap.has(componentOrElement)) {
return ReactMount.getNodeFromInstance(componentOrElement);

var inst = ReactInstanceMap.get(componentOrElement);
if (inst) {
inst = getNativeComponentFromComposite(inst);
// TODO: Once we store the DOM node on the component instance, this can use
// that directly instead of searching the DOM.
return inst ? ReactMount.getNode(inst._rootNodeID) : null;
}

if (typeof componentOrElement.render === 'function') {
invariant(
false,
'findDOMNode was called on an unmounted component.'
);
} else {
invariant(
false,
'Element appears to be neither ReactComponent nor DOMNode (keys: %s)',
Object.keys(componentOrElement)
);
}
invariant(
componentOrElement.render == null ||
typeof componentOrElement.render !== 'function',
'findDOMNode was called on an unmounted component.'
);
invariant(
false,
'Element appears to be neither ReactComponent nor DOMNode (keys: %s)',
Object.keys(componentOrElement)
);
}

module.exports = findDOMNode;
4 changes: 4 additions & 0 deletions src/renderers/shared/reconciler/ReactCompositeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ var ReactCompositeComponentMixin = {
this._pendingReplaceState = false;
this._pendingForceUpdate = false;

this._renderedElement = null;
this._renderedComponent = null;

this._context = null;
Expand Down Expand Up @@ -280,6 +281,7 @@ var ReactCompositeComponentMixin = {
renderedElement = this._renderValidatedComponent();
}

this._renderedElement = renderedElement;
this._renderedComponent = this._instantiateReactComponent(
renderedElement
);
Expand Down Expand Up @@ -311,6 +313,7 @@ var ReactCompositeComponentMixin = {
}

ReactReconciler.unmountComponent(this._renderedComponent);
this._renderedElement = null;
this._renderedComponent = null;
this._instance = null;

Expand Down Expand Up @@ -732,6 +735,7 @@ var ReactCompositeComponentMixin = {
var prevComponentID = prevComponentInstance._rootNodeID;
ReactReconciler.unmountComponent(prevComponentInstance);

this._renderedElement = nextRenderedElement;
this._renderedComponent = this._instantiateReactComponent(
nextRenderedElement
);
Expand Down
3 changes: 0 additions & 3 deletions src/renderers/shared/reconciler/ReactEmptyComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
'use strict';

var ReactElement = require('ReactElement');
var ReactEmptyComponentRegistry = require('ReactEmptyComponentRegistry');
var ReactReconciler = require('ReactReconciler');

var assign = require('Object.assign');
Expand All @@ -34,7 +33,6 @@ assign(ReactEmptyComponent.prototype, {
construct: function(element) {
},
mountComponent: function(rootID, transaction, context) {
ReactEmptyComponentRegistry.registerNullComponentID(rootID);
this._rootNodeID = rootID;
return ReactReconciler.mountComponent(
this._renderedComponent,
Expand All @@ -47,7 +45,6 @@ assign(ReactEmptyComponent.prototype, {
},
unmountComponent: function(rootID, transaction, context) {
ReactReconciler.unmountComponent(this._renderedComponent);
ReactEmptyComponentRegistry.deregisterNullComponentID(this._rootNodeID);
this._rootNodeID = null;
this._renderedComponent = null;
},
Expand Down
48 changes: 0 additions & 48 deletions src/renderers/shared/reconciler/ReactEmptyComponentRegistry.js

This file was deleted.

0 comments on commit a39217a

Please sign in to comment.