Make ReactMount.findComponentRoot breadth-first & non-recursive.

This function needs to be as fast as possible for those cases when
`ReactID.getNode` can't rely on the `nodeCache`.

Breadth-first search prevents us from diving too deeply down the wrong
branches when the sought-after node can be found at a shallower level.

The queue required for breadth-first search is implemented by a single
array indexed by `childIndex`. To save space, only the `.firstChild` nodes
are stored, and we use `.nextSibling` to iterate over the other siblings
in a `while` loop.
This commit is contained in:
Ben Newman
2013-07-08 11:50:34 -07:00
committed by Paul O’Shannessy
parent 917e101c2c
commit a5ddb07cb3
+21 -9
View File
@@ -284,18 +284,30 @@ var ReactInstanceHandles = {
* @internal
*/
findComponentRoot: function(ancestorNode, id) {
var child = ancestorNode.firstChild;
while (child) {
var childID = ReactID.getID(child);
if (childID) {
if (id === childID) {
return child;
} else if (isAncestorIDOf(childID, id)) {
return ReactInstanceHandles.findComponentRoot(child, id);
var firstChildren = [ancestorNode.firstChild];
var childIndex = 0;
while (childIndex < firstChildren.length) {
var child = firstChildren[childIndex++];
while (child) {
var childID = ReactID.getID(child);
if (childID) {
if (id === childID) {
return child;
} else if (isAncestorIDOf(childID, id)) {
// If we find a child whose ID is an ancestor of the given ID,
// then we can be sure that we only want to search the subtree
// rooted at this child, so we can throw out the rest of the
// search state.
firstChildren.length = childIndex = 0;
firstChildren.push(child.firstChild);
break;
}
}
child = child.nextSibling;
}
child = child.nextSibling;
}
global.console && console.error && console.error(
'Error while invoking `findComponentRoot` with the following ' +
'ancestor node:',