diff --git a/src/isomorphic/ReactDebugTool.js b/src/isomorphic/ReactDebugTool.js
index 6dfd605b0b..8c45afedc2 100644
--- a/src/isomorphic/ReactDebugTool.js
+++ b/src/isomorphic/ReactDebugTool.js
@@ -58,6 +58,9 @@ var ReactDebugTool = {
onSetState() {
emitEvent('onSetState');
},
+ onSetIsTopLevelWrapper(debugID, isTopLevelWrapper) {
+ emitEvent('onSetIsTopLevelWrapper', debugID, isTopLevelWrapper);
+ },
onSetIsComposite(debugID, isComposite) {
emitEvent('onSetIsComposite', debugID, isComposite);
},
diff --git a/src/isomorphic/devtools/ReactComponentTreeDevtool.js b/src/isomorphic/devtools/ReactComponentTreeDevtool.js
index 0f65e1cfc2..fc30ffbbdb 100644
--- a/src/isomorphic/devtools/ReactComponentTreeDevtool.js
+++ b/src/isomorphic/devtools/ReactComponentTreeDevtool.js
@@ -13,11 +13,15 @@
var invariant = require('invariant');
+var isTopLevelWrapperByID = {};
var unmountedContainerIDs = [];
var allChildIDsByContainerID = {};
var tree = {};
function updateTree(id, update) {
+ if (isTopLevelWrapperByID[id]) {
+ return;
+ }
if (!tree[id]) {
tree[id] = {};
}
@@ -44,6 +48,13 @@ function purgeTree(id) {
}
var ReactComponentTreeDevtool = {
+ onSetIsTopLevelWrapper(id, isTopLevelWrapper) {
+ if (isTopLevelWrapper) {
+ delete tree[id];
+ isTopLevelWrapperByID[id] = true;
+ }
+ },
+
onSetIsComposite(id, isComposite) {
updateTree(id, item => item.isComposite = isComposite);
},
@@ -53,45 +64,44 @@ var ReactComponentTreeDevtool = {
},
onSetChildren(id, nextChildIDs) {
- var prevChildIDs;
updateTree(id, item => {
- prevChildIDs = item.childIDs || [];
+ var prevChildIDs = item.childIDs || [];
item.childIDs = nextChildIDs;
- });
- prevChildIDs.forEach(prevChildID => {
- if (tree[prevChildID] && nextChildIDs.indexOf(prevChildID) === -1) {
- tree[prevChildID].parentID = null;
- }
- });
+ prevChildIDs.forEach(prevChildID => {
+ var prevChild = tree[prevChildID];
+ if (prevChild && nextChildIDs.indexOf(prevChildID) === -1) {
+ prevChild.parentID = null;
+ }
+ });
- nextChildIDs.forEach(nextChildID => {
- var item = tree[nextChildID];
+ nextChildIDs.forEach(nextChildID => {
+ var nextChild = tree[nextChildID];
+ invariant(
+ nextChild,
+ 'Expected devtool events to fire for the child ' +
+ 'before its parent includes it in onSetChildren().'
+ );
+ invariant(
+ nextChild.isComposite != null,
+ 'Expected onSetIsComposite() to fire for the child ' +
+ 'before its parent includes it in onSetChildren().'
+ );
+ invariant(
+ nextChild.displayName != null,
+ 'Expected onSetDisplayName() to fire for the child ' +
+ 'before its parent includes it in onSetChildren().'
+ );
+ invariant(
+ nextChild.childIDs != null || nextChild.text != null,
+ 'Expected either onSetChildren() or onSetText() to fire for the child ' +
+ 'before its parent includes it in onSetChildren().'
+ );
- invariant(
- item,
- 'Expected devtool events to fire for the child ' +
- 'before its parent includes it in onSetChildren().'
- );
- invariant(
- item.isComposite != null,
- 'Expected onSetIsComposite() to fire for the child ' +
- 'before its parent includes it in onSetChildren().'
- );
- invariant(
- item.displayName != null,
- 'Expected onSetDisplayName() to fire for the child ' +
- 'before its parent includes it in onSetChildren().'
- );
- invariant(
- item.childIDs != null || item.text != null,
- 'Expected either onSetChildren() or onSetText() to fire for the child ' +
- 'before its parent includes it in onSetChildren().'
- );
-
- if (tree[nextChildID] && prevChildIDs.indexOf(nextChildID) === -1) {
- tree[nextChildID].parentID = id;
- }
+ if (prevChildIDs.indexOf(nextChildID) === -1) {
+ nextChild.parentID = id;
+ }
+ });
});
},
diff --git a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js
index ced1b0f411..f8f8a8c4da 100644
--- a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js
+++ b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js
@@ -36,7 +36,7 @@ describe('ReactComponentTreeDevtool', () => {
ReactDebugTool.removeDevtool(ReactComponentTreeDevtool);
});
- function denormalizeTree(
+ function explodeTree(
tree,
rootID,
includeOwner = false,
@@ -54,7 +54,7 @@ describe('ReactComponentTreeDevtool', () => {
if (item.childIDs) {
result.children = item.childIDs.map(childID =>
- denormalizeTree(tree, childID, includeOwner, rootID)
+ explodeTree(tree, childID, includeOwner, rootID)
);
}
if (item.text != null) {
@@ -89,7 +89,7 @@ describe('ReactComponentTreeDevtool', () => {
pairs.forEach(([element, expectedTree]) => {
currentElement = element;
ReactDOM.render(