diff --git a/src/isomorphic/ReactDebugTool.js b/src/isomorphic/ReactDebugTool.js index 005378b76d76c..f88513b387157 100644 --- a/src/isomorphic/ReactDebugTool.js +++ b/src/isomorphic/ReactDebugTool.js @@ -48,45 +48,54 @@ var currentTimerDebugID = null; var currentTimerStartTime = null; var currentTimerType = null; +function clearHistory() { + ReactComponentTreeDevtool.purgeUnmountedComponents(); + ReactNativeOperationHistoryDevtool.clearHistory(); +} + +function getTreeSnapshot(registeredIDs) { + return registeredIDs.reduce((tree, id) => { + var ownerID = ReactComponentTreeDevtool.getOwnerID(id); + var parentID = ReactComponentTreeDevtool.getParentID(id); + tree[id] = { + displayName: ReactComponentTreeDevtool.getDisplayName(id), + text: ReactComponentTreeDevtool.getText(id), + updateCount: ReactComponentTreeDevtool.getUpdateCount(id), + childIDs: ReactComponentTreeDevtool.getChildIDs(id), + // Text nodes don't have owners but this is close enough. + ownerID: ownerID || ReactComponentTreeDevtool.getOwnerID(parentID), + parentID, + }; + return tree; + }, {}); +} + function resetMeasurements() { if (__DEV__) { + var previousStartTime = currentFlushStartTime; + var previousMeasurements = currentFlushMeasurements || []; + var previousOperations = ReactNativeOperationHistoryDevtool.getHistory(); + if (!isProfiling || currentFlushNesting === 0) { currentFlushStartTime = null; currentFlushMeasurements = null; + clearHistory(); return; } - var previousStartTime = currentFlushStartTime; - var previousMeasurements = currentFlushMeasurements || []; - var previousOperations = ReactNativeOperationHistoryDevtool.getHistory(); - if (previousMeasurements.length || previousOperations.length) { var registeredIDs = ReactComponentTreeDevtool.getRegisteredIDs(); flushHistory.push({ duration: performanceNow() - previousStartTime, measurements: previousMeasurements || [], operations: previousOperations || [], - treeSnapshot: registeredIDs.reduce((tree, id) => { - var ownerID = ReactComponentTreeDevtool.getOwnerID(id); - var parentID = ReactComponentTreeDevtool.getParentID(id); - tree[id] = { - displayName: ReactComponentTreeDevtool.getDisplayName(id), - text: ReactComponentTreeDevtool.getText(id), - updateCount: ReactComponentTreeDevtool.getUpdateCount(id), - childIDs: ReactComponentTreeDevtool.getChildIDs(id), - // Text nodes don't have owners but this is close enough. - ownerID: ownerID || ReactComponentTreeDevtool.getOwnerID(parentID), - parentID, - }; - return tree; - }, {}), + treeSnapshot: getTreeSnapshot(registeredIDs), }); } + clearHistory(); currentFlushStartTime = performanceNow(); currentFlushMeasurements = []; - ReactComponentTreeDevtool.purgeUnmountedComponents(); - ReactNativeOperationHistoryDevtool.clearHistory(); } } diff --git a/src/isomorphic/__tests__/ReactPerf-test.js b/src/isomorphic/__tests__/ReactPerf-test.js index c81a4e82a79d9..644bc618b849f 100644 --- a/src/isomorphic/__tests__/ReactPerf-test.js +++ b/src/isomorphic/__tests__/ReactPerf-test.js @@ -241,6 +241,21 @@ describe('ReactPerf', function() { }); }); + it('should include stats for components unmounted during measurement', function() { + var container = document.createElement('div'); + var measurements = measure(() => { + ReactDOM.render(
, container); + ReactDOM.render(
, container); + }); + expect(ReactPerf.getExclusive(measurements)).toEqual([{ + key: 'Div', + instanceCount: 3, + counts: { ctor: 3, render: 4 }, + durations: { ctor: 3, render: 4 }, + totalDuration: 7, + }]); + }); + it('warns once when using getMeasurementsSummaryMap', function() { var measurements = measure(() => {}); spyOn(console, 'error'); diff --git a/src/isomorphic/devtools/ReactComponentTreeDevtool.js b/src/isomorphic/devtools/ReactComponentTreeDevtool.js index 57e85b39dfc3c..85902c30d09cc 100644 --- a/src/isomorphic/devtools/ReactComponentTreeDevtool.js +++ b/src/isomorphic/devtools/ReactComponentTreeDevtool.js @@ -106,6 +106,11 @@ var ReactComponentTreeDevtool = { }, purgeUnmountedComponents() { + if (ReactComponentTreeDevtool._preventPurging) { + // Should only be used for testing. + return; + } + Object.keys(tree) .filter(id => !tree[id].isMounted) .forEach(purgeDeep); diff --git a/src/isomorphic/devtools/ReactNativeOperationHistoryDevtool.js b/src/isomorphic/devtools/ReactNativeOperationHistoryDevtool.js index 50478cc405d6c..46b8194465db2 100644 --- a/src/isomorphic/devtools/ReactNativeOperationHistoryDevtool.js +++ b/src/isomorphic/devtools/ReactNativeOperationHistoryDevtool.js @@ -23,6 +23,11 @@ var ReactNativeOperationHistoryDevtool = { }, clearHistory() { + if (ReactNativeOperationHistoryDevtool._preventClearing) { + // Should only be used for tests. + return; + } + history = []; }, diff --git a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js index 106307d0d25ac..f170724294b7d 100644 --- a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js +++ b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.js @@ -97,13 +97,20 @@ describe('ReactComponentTreeDevtool', () => { // Ensure the tree is correct on every step. pairs.forEach(([element, expectedTree]) => { currentElement = element; + + // Mount a new tree or update the existing tree. ReactDOM.render(, node); expect(getActualTree()).toEqual(expectedTree); + + // Purging should have no effect + // on the tree we expect to see. ReactComponentTreeDevtool.purgeUnmountedComponents(); expect(getActualTree()).toEqual(expectedTree); }); + + // Unmounting the root node should purge + // the whole subtree automatically. ReactDOM.unmountComponentAtNode(node); - ReactComponentTreeDevtool.purgeUnmountedComponents(); expect(getActualTree()).toBe(undefined); expect(getRootDisplayNames()).toEqual([]); expect(getRegisteredDisplayNames()).toEqual([]); @@ -112,8 +119,23 @@ describe('ReactComponentTreeDevtool', () => { // Ensure the tree is correct on every step. pairs.forEach(([element, expectedTree]) => { currentElement = element; + + // Rendering to string while not profiling + // should not produce any entries after it finishes. + ReactDOMServer.renderToString(); + expect(getActualTree()).toBe(undefined); + expect(getRootDisplayNames()).toEqual([]); + expect(getRegisteredDisplayNames()).toEqual([]); + + // To test it, we tell the devtool to ignore next purge + // so the cleanup request by ReactDebugTool is ignored. + // This lets us make assertions on the tree before it + // is destroyed. + ReactComponentTreeDevtool._preventPurging = true; ReactDOMServer.renderToString(); + ReactComponentTreeDevtool._preventPurging = false; expect(getActualTree()).toEqual(expectedTree); + ReactComponentTreeDevtool.purgeUnmountedComponents(); expect(getActualTree()).toBe(undefined); expect(getRootDisplayNames()).toEqual([]); @@ -1631,7 +1653,7 @@ describe('ReactComponentTreeDevtool', () => { assertTreeMatches([element, tree], {includeOwnerDisplayName: true}); }); - it('preserves unmounted components until purge', () => { + it('purges unmounted components automatically', () => { var node = document.createElement('div'); var renderBar = true; var fooInstance; @@ -1666,31 +1688,15 @@ describe('ReactComponentTreeDevtool', () => { renderBar = false; ReactDOM.render(, node); expect( - getTree(barInstance._debugID, { - includeParentDisplayName: true, - expectedParentID: fooInstance._debugID, - }) + getTree(barInstance._debugID, {expectedParentID: null}) ).toEqual({ - displayName: 'Bar', - parentDisplayName: 'Foo', + displayName: 'Unknown', children: [], }); ReactDOM.unmountComponentAtNode(node); expect( - getTree(barInstance._debugID, { - includeParentDisplayName: true, - expectedParentID: fooInstance._debugID, - }) - ).toEqual({ - displayName: 'Bar', - parentDisplayName: 'Foo', - children: [], - }); - - ReactComponentTreeDevtool.purgeUnmountedComponents(); - expect( - getTree(barInstance._debugID, {includeParentDisplayName: true}) + getTree(barInstance._debugID, {expectedParentID: null}) ).toEqual({ displayName: 'Unknown', children: [], @@ -1719,7 +1725,7 @@ describe('ReactComponentTreeDevtool', () => { ReactDOM.unmountComponentAtNode(node); expect(ReactComponentTreeDevtool.getUpdateCount(divID)).toEqual(0); - expect(ReactComponentTreeDevtool.getUpdateCount(spanID)).toEqual(2); + expect(ReactComponentTreeDevtool.getUpdateCount(spanID)).toEqual(0); }); it('does not report top-level wrapper as a root', () => { @@ -1733,12 +1739,6 @@ describe('ReactComponentTreeDevtool', () => { ReactDOM.unmountComponentAtNode(node); expect(getRootDisplayNames()).toEqual([]); - - ReactComponentTreeDevtool.purgeUnmountedComponents(); - expect(getRootDisplayNames()).toEqual([]); - - // This currently contains TopLevelWrapper until purge - // so we only check it at the very end. expect(getRegisteredDisplayNames()).toEqual([]); }); }); diff --git a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js index 3113d6fcad898..f3b026b459ccf 100644 --- a/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js +++ b/src/isomorphic/devtools/__tests__/ReactComponentTreeDevtool-test.native.js @@ -119,13 +119,20 @@ describe('ReactComponentTreeDevtool', () => { // Ensure the tree is correct on every step. pairs.forEach(([element, expectedTree]) => { currentElement = element; + + // Mount a new tree or update the existing tree. ReactNative.render(, 1); expect(getActualTree()).toEqual(expectedTree); + + // Purging should have no effect + // on the tree we expect to see. ReactComponentTreeDevtool.purgeUnmountedComponents(); expect(getActualTree()).toEqual(expectedTree); }); + + // Unmounting the root node should purge + // the whole subtree automatically. ReactNative.unmountComponentAtNode(1); - ReactComponentTreeDevtool.purgeUnmountedComponents(); expect(getActualTree()).toBe(undefined); expect(getRootDisplayNames()).toEqual([]); expect(getRegisteredDisplayNames()).toEqual([]); @@ -134,10 +141,13 @@ describe('ReactComponentTreeDevtool', () => { // Ensure the tree is correct on every step. pairs.forEach(([element, expectedTree]) => { currentElement = element; + + // Mount a new tree. ReactNative.render(, 1); - ReactNative.unmountComponentAtNode(1); expect(getActualTree()).toEqual(expectedTree); - ReactComponentTreeDevtool.purgeUnmountedComponents(); + + // Unmounting should clean it up. + ReactNative.unmountComponentAtNode(1); expect(getActualTree()).toBe(undefined); expect(getRootDisplayNames()).toEqual([]); expect(getRegisteredDisplayNames()).toEqual([]); @@ -1620,7 +1630,7 @@ describe('ReactComponentTreeDevtool', () => { assertTreeMatches([element, tree], {includeOwnerDisplayName: true}); }); - it('preserves unmounted components until purge', () => { + it('purges unmounted components automatically', () => { var renderBar = true; var fooInstance; var barInstance; @@ -1654,31 +1664,15 @@ describe('ReactComponentTreeDevtool', () => { renderBar = false; ReactNative.render(, 1); expect( - getTree(barInstance._debugID, { - includeParentDisplayName: true, - expectedParentID: fooInstance._debugID, - }) + getTree(barInstance._debugID, {expectedParentID: null}) ).toEqual({ - displayName: 'Bar', - parentDisplayName: 'Foo', + displayName: 'Unknown', children: [], }); ReactNative.unmountComponentAtNode(1); expect( - getTree(barInstance._debugID, { - includeParentDisplayName: true, - expectedParentID: fooInstance._debugID, - }) - ).toEqual({ - displayName: 'Bar', - parentDisplayName: 'Foo', - children: [], - }); - - ReactComponentTreeDevtool.purgeUnmountedComponents(); - expect( - getTree(barInstance._debugID, {includeParentDisplayName: true}) + getTree(barInstance._debugID, {expectedParentID: null}) ).toEqual({ displayName: 'Unknown', children: [], @@ -1705,7 +1699,7 @@ describe('ReactComponentTreeDevtool', () => { ReactNative.unmountComponentAtNode(1); expect(ReactComponentTreeDevtool.getUpdateCount(viewID)).toEqual(0); - expect(ReactComponentTreeDevtool.getUpdateCount(imageID)).toEqual(2); + expect(ReactComponentTreeDevtool.getUpdateCount(imageID)).toEqual(0); }); it('does not report top-level wrapper as a root', () => { @@ -1717,12 +1711,6 @@ describe('ReactComponentTreeDevtool', () => { ReactNative.unmountComponentAtNode(1); expect(getRootDisplayNames()).toEqual([]); - - ReactComponentTreeDevtool.purgeUnmountedComponents(); - expect(getRootDisplayNames()).toEqual([]); - - // This currently contains TopLevelWrapper until purge - // so we only check it at the very end. expect(getRegisteredDisplayNames()).toEqual([]); }); }); diff --git a/src/isomorphic/devtools/__tests__/ReactNativeOperationHistoryDevtool-test.js b/src/isomorphic/devtools/__tests__/ReactNativeOperationHistoryDevtool-test.js index 73ee7511d1ecb..d6cc9caee9c7e 100644 --- a/src/isomorphic/devtools/__tests__/ReactNativeOperationHistoryDevtool-test.js +++ b/src/isomorphic/devtools/__tests__/ReactNativeOperationHistoryDevtool-test.js @@ -35,6 +35,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { describe('mount', () => { it('gets recorded for native roots', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + var node = document.createElement('div'); ReactDOM.render(

Hi.

, node); var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); @@ -49,6 +51,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { }); it('gets recorded for composite roots', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + function Foo() { return

Hi.

; } @@ -66,6 +70,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { }); it('gets ignored for composite roots that return null', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + function Foo() { return null; } @@ -103,6 +109,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { describe('update styles', () => { it('gets recorded during mount', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + var node = document.createElement('div'); ReactDOM.render(
{ var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node); ReactDOM.render(
{ var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
{ describe('update attribute', () => { describe('simple attribute', () => { it('gets recorded during mount', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + var node = document.createElement('div'); ReactDOM.render(
, node); var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); @@ -229,6 +243,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node); ReactDOM.render(
, node); ReactDOM.render(
, node); @@ -263,6 +279,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node); ReactDOM.render(
, node); assertHistoryMatches([{ @@ -279,6 +297,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { describe('custom attribute', () => { it('gets recorded during mount', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + var node = document.createElement('div'); ReactDOM.render(
, node); var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); @@ -313,6 +333,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node); ReactDOM.render(
, node); ReactDOM.render(
, node); @@ -342,6 +364,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { describe('attribute on a web component', () => { it('gets recorded during mount', () => { + ReactNativeOperationHistoryDevtool._preventClearing = true; + var node = document.createElement('div'); ReactDOM.render(, node); var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); @@ -376,6 +400,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(, node); ReactDOM.render(, node); ReactDOM.render(, node); @@ -412,6 +438,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
Bye.
, node); assertHistoryMatches([{ instanceID: inst._debugID, @@ -426,6 +454,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
Bye.
, node); assertHistoryMatches([{ instanceID: inst._debugID, @@ -440,6 +470,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
Bye.
, node); assertHistoryMatches([{ instanceID: inst._debugID, @@ -461,6 +493,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { ReactDOM.render(
Hi.
, node); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
Hi.
, node); assertHistoryMatches([]); }); @@ -474,6 +508,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst2 = ReactDOMComponentTree.getInstanceFromNode(node.firstChild.childNodes[3]); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
{'Bye.'}{43}
, node); assertHistoryMatches([{ instanceID: inst1._debugID, @@ -491,6 +527,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { ReactDOM.render(
{'Hi.'}{42}
, node); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
{'Hi.'}{42}
, node); assertHistoryMatches([]); }); @@ -510,6 +548,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + element = ; ReactDOM.render(, node); assertHistoryMatches([{ @@ -551,6 +591,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { ReactDOM.render(, node); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + element =
; ReactDOM.render(, node); assertHistoryMatches([]); @@ -564,6 +606,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node @@ -584,6 +628,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node @@ -601,6 +647,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node @@ -628,6 +676,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { ); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node @@ -643,6 +693,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(

, node); assertHistoryMatches([{ instanceID: inst._debugID, @@ -659,6 +711,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(

, node); assertHistoryMatches([{ instanceID: inst._debugID, @@ -675,6 +729,8 @@ describe('ReactNativeOperationHistoryDevtool', () => { var inst = ReactDOMComponentTree.getInstanceFromNode(node.firstChild); ReactNativeOperationHistoryDevtool.clearHistory(); + ReactNativeOperationHistoryDevtool._preventClearing = true; + ReactDOM.render(
, node); assertHistoryMatches([{ instanceID: inst._debugID, diff --git a/src/renderers/dom/server/ReactServerRendering.js b/src/renderers/dom/server/ReactServerRendering.js index 73ce86c46045d..ee57e07438e98 100644 --- a/src/renderers/dom/server/ReactServerRendering.js +++ b/src/renderers/dom/server/ReactServerRendering.js @@ -37,6 +37,9 @@ function renderToStringImpl(element, makeStaticMarkup) { transaction = ReactServerRenderingTransaction.getPooled(makeStaticMarkup); return transaction.perform(function() { + if (__DEV__) { + ReactInstrumentation.debugTool.onBeginFlush(); + } var componentInstance = instantiateReactComponent(element); var markup = ReactReconciler.mountComponent( componentInstance, @@ -49,6 +52,7 @@ function renderToStringImpl(element, makeStaticMarkup) { ReactInstrumentation.debugTool.onUnmountComponent( componentInstance._debugID ); + ReactInstrumentation.debugTool.onEndFlush(); } if (!makeStaticMarkup) { markup = ReactMarkupChecksum.addChecksumToMarkup(markup); diff --git a/src/renderers/native/ReactNativeMount.js b/src/renderers/native/ReactNativeMount.js index 0e5c4838bbdd8..0694ec262c2b5 100644 --- a/src/renderers/native/ReactNativeMount.js +++ b/src/renderers/native/ReactNativeMount.js @@ -216,8 +216,14 @@ var ReactNativeMount = { if (!instance) { return false; } + if (__DEV__) { + ReactInstrumentation.debugTool.onBeginFlush(); + } ReactNativeMount.unmountComponentFromNode(instance, containerTag); delete ReactNativeMount._instancesByContainerID[containerTag]; + if (__DEV__) { + ReactInstrumentation.debugTool.onEndFlush(); + } return true; },