Devtools should be able to clean up the tree on client rendering
This commit is contained in:
@@ -73,17 +73,17 @@ var ReactDebugTool = {
|
||||
onSetText(debugID, text) {
|
||||
emitEvent('onSetText', debugID, text);
|
||||
},
|
||||
onMountRootComponent(internalInstance) {
|
||||
emitEvent('onMountRootComponent', internalInstance);
|
||||
onMountRootComponent(debugID) {
|
||||
emitEvent('onMountRootComponent', debugID);
|
||||
},
|
||||
onMountComponent(internalInstance) {
|
||||
emitEvent('onMountComponent', internalInstance);
|
||||
onMountComponent(debugID) {
|
||||
emitEvent('onMountComponent', debugID);
|
||||
},
|
||||
onUpdateComponent(internalInstance) {
|
||||
emitEvent('onUpdateComponent', internalInstance);
|
||||
onUpdateComponent(debugID) {
|
||||
emitEvent('onUpdateComponent', debugID);
|
||||
},
|
||||
onUnmountComponent(internalInstance) {
|
||||
emitEvent('onUnmountComponent', internalInstance);
|
||||
onUnmountComponent(debugID) {
|
||||
emitEvent('onUnmountComponent', debugID);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -22,22 +22,22 @@ describe('ReactDebugTool', () => {
|
||||
function createDevtool() {
|
||||
var tree = {};
|
||||
|
||||
function updateTree(debugID, update) {
|
||||
if (!tree[debugID]) {
|
||||
tree[debugID] = {};
|
||||
function updateTree(id, update) {
|
||||
if (!tree[id]) {
|
||||
tree[id] = {};
|
||||
}
|
||||
update(tree[debugID]);
|
||||
update(tree[id]);
|
||||
}
|
||||
|
||||
function getTree(debugID, includeOwner) {
|
||||
var item = tree[debugID];
|
||||
function getTree(id, includeOwner) {
|
||||
var item = tree[id];
|
||||
var result = {
|
||||
isComposite: item.isComposite,
|
||||
displayName: item.displayName,
|
||||
};
|
||||
if (item.childDebugIDs) {
|
||||
result.children = item.childDebugIDs.map(childDebugID =>
|
||||
getTree(childDebugID, includeOwner)
|
||||
if (item.childIDs) {
|
||||
result.children = item.childIDs.map(childID =>
|
||||
getTree(childID, includeOwner)
|
||||
);
|
||||
}
|
||||
if (item.text != null) {
|
||||
@@ -49,29 +49,57 @@ describe('ReactDebugTool', () => {
|
||||
return result;
|
||||
}
|
||||
|
||||
function purgeTree(id) {
|
||||
var item = tree[id];
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
var {childIDs} = item;
|
||||
delete tree[id];
|
||||
|
||||
if (childIDs) {
|
||||
childIDs.forEach(purgeTree);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
onSetIsComposite(debugID, isComposite) {
|
||||
updateTree(debugID, item => item.isComposite = isComposite);
|
||||
onSetIsComposite(id, isComposite) {
|
||||
updateTree(id, item => item.isComposite = isComposite);
|
||||
},
|
||||
onSetDisplayName(debugID, displayName) {
|
||||
updateTree(debugID, item => item.displayName = displayName);
|
||||
|
||||
onSetDisplayName(id, displayName) {
|
||||
updateTree(id, item => item.displayName = displayName);
|
||||
},
|
||||
onSetChildren(debugID, childDebugIDs) {
|
||||
childDebugIDs.forEach(childDebugID => {
|
||||
var childItem = tree[childDebugID];
|
||||
|
||||
onSetChildren(id, childIDs) {
|
||||
childIDs.forEach(childID => {
|
||||
var childItem = tree[childID];
|
||||
expect(childItem).toBeDefined();
|
||||
expect(childItem.isComposite).toBeDefined();
|
||||
expect(childItem.displayName).toBeDefined();
|
||||
expect(childItem.childDebugIDs || childItem.text).toBeDefined();
|
||||
expect(childItem.childIDs || childItem.text).toBeDefined();
|
||||
});
|
||||
updateTree(debugID, item => item.childDebugIDs = childDebugIDs);
|
||||
|
||||
updateTree(id, item => item.childIDs = childIDs);
|
||||
},
|
||||
onSetOwner(debugID, ownerDebugID) {
|
||||
updateTree(debugID, item => item.ownerDebugID = ownerDebugID);
|
||||
|
||||
onSetOwner(id, ownerDebugID) {
|
||||
updateTree(id, item => item.ownerDebugID = ownerDebugID);
|
||||
},
|
||||
onSetText(debugID, text) {
|
||||
updateTree(debugID, item => item.text = text);
|
||||
|
||||
onSetText(id, text) {
|
||||
updateTree(id, item => item.text = text);
|
||||
},
|
||||
|
||||
onUnmountComponent(id) {
|
||||
purgeTree(id);
|
||||
},
|
||||
|
||||
getRegisteredDebugIDs() {
|
||||
return Object.keys(tree);
|
||||
},
|
||||
|
||||
getTree(rootDebugID, includeOwner) {
|
||||
return getTree(rootDebugID, includeOwner);
|
||||
},
|
||||
@@ -119,6 +147,9 @@ describe('ReactDebugTool', () => {
|
||||
);
|
||||
expect(actualTree).toEqual(expectedTree);
|
||||
});
|
||||
|
||||
ReactDOM.unmountComponentAtNode(node);
|
||||
expect(devtool.getRegisteredDebugIDs()).toEqual([]);
|
||||
}
|
||||
|
||||
describe('mount', () => {
|
||||
|
||||
@@ -349,7 +349,7 @@ var ReactMount = {
|
||||
instancesByReactRootID[wrapperID] = componentInstance;
|
||||
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onMountRootComponent(componentInstance);
|
||||
ReactInstrumentation.debugTool.onMountRootComponent(componentInstance._debugID);
|
||||
}
|
||||
|
||||
return componentInstance;
|
||||
|
||||
@@ -453,6 +453,7 @@ function ReactDOMComponent(element) {
|
||||
this._flags = 0;
|
||||
if (__DEV__) {
|
||||
this._ancestorInfo = null;
|
||||
this._contentDebugID = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,11 +759,11 @@ ReactDOMComponent.Mixin = {
|
||||
if (contentToUse != null) {
|
||||
// TODO: Validate that text is allowed as a child of this node
|
||||
if (__DEV__) {
|
||||
var inlinedTextDebugID = this._debugID + '#text';
|
||||
ReactInstrumentation.debugTool.onSetIsComposite(inlinedTextDebugID, false);
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(inlinedTextDebugID, '#text');
|
||||
ReactInstrumentation.debugTool.onSetText(inlinedTextDebugID, '' + contentToUse);
|
||||
ReactInstrumentation.debugTool.onSetChildren(this._debugID, [inlinedTextDebugID]);
|
||||
this._contentDebugID = this._debugID + '#text';
|
||||
ReactInstrumentation.debugTool.onSetIsComposite(this._contentDebugID, false);
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(this._contentDebugID, '#text');
|
||||
ReactInstrumentation.debugTool.onSetText(this._contentDebugID, '' + contentToUse);
|
||||
ReactInstrumentation.debugTool.onSetChildren(this._debugID, [this._contentDebugID]);
|
||||
}
|
||||
DOMLazyTree.queueText(lazyTree, contentToUse);
|
||||
} else if (childrenToUse != null) {
|
||||
@@ -1020,11 +1021,11 @@ ReactDOMComponent.Mixin = {
|
||||
if (lastContent !== nextContent) {
|
||||
this.updateTextContent('' + nextContent);
|
||||
if (__DEV__) {
|
||||
var inlinedTextDebugID = this._debugID + '#text';
|
||||
ReactInstrumentation.debugTool.onSetIsComposite(inlinedTextDebugID, false);
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(inlinedTextDebugID, '#text');
|
||||
ReactInstrumentation.debugTool.onSetText(inlinedTextDebugID, '' + nextContent);
|
||||
ReactInstrumentation.debugTool.onSetChildren(this._debugID, [inlinedTextDebugID]);
|
||||
this._contentDebugID = this._debugID + '#text';
|
||||
ReactInstrumentation.debugTool.onSetIsComposite(this._contentDebugID, false);
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(this._contentDebugID, '#text');
|
||||
ReactInstrumentation.debugTool.onSetText(this._contentDebugID, '' + nextContent);
|
||||
ReactInstrumentation.debugTool.onSetChildren(this._debugID, [this._contentDebugID]);
|
||||
}
|
||||
}
|
||||
} else if (nextHtml != null) {
|
||||
@@ -1035,6 +1036,13 @@ ReactDOMComponent.Mixin = {
|
||||
ReactInstrumentation.debugTool.onSetChildren(this._debugID, []);
|
||||
}
|
||||
} else if (nextChildren != null) {
|
||||
if (__DEV__) {
|
||||
if (this._contentDebugID) {
|
||||
ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
|
||||
this._contentDebugID = null;
|
||||
}
|
||||
}
|
||||
|
||||
this.updateChildren(nextChildren, transaction, context);
|
||||
}
|
||||
},
|
||||
@@ -1096,6 +1104,11 @@ ReactDOMComponent.Mixin = {
|
||||
this._rootNodeID = null;
|
||||
this._domID = null;
|
||||
this._wrapperState = null;
|
||||
|
||||
if (this._contentDebugID) {
|
||||
ReactInstrumentation.debugTool.onUnmountComponent(this._contentDebugID);
|
||||
this._contentDebugID = null;
|
||||
}
|
||||
},
|
||||
|
||||
getPublicInstance: function() {
|
||||
|
||||
@@ -53,7 +53,7 @@ var ReactReconciler = {
|
||||
transaction.getReactMountReady().enqueue(attachRefs, internalInstance);
|
||||
}
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onMountComponent(internalInstance);
|
||||
ReactInstrumentation.debugTool.onMountComponent(internalInstance._debugID);
|
||||
}
|
||||
return markup;
|
||||
},
|
||||
@@ -76,7 +76,7 @@ var ReactReconciler = {
|
||||
ReactRef.detachRefs(internalInstance, internalInstance._currentElement);
|
||||
internalInstance.unmountComponent(safely);
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onUnmountComponent(internalInstance);
|
||||
ReactInstrumentation.debugTool.onUnmountComponent(internalInstance._debugID);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -128,7 +128,7 @@ var ReactReconciler = {
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance);
|
||||
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -145,7 +145,7 @@ var ReactReconciler = {
|
||||
) {
|
||||
internalInstance.performUpdateIfNecessary(transaction);
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance);
|
||||
ReactInstrumentation.debugTool.onUpdateComponent(internalInstance._debugID);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user