Merge pull request #6633 from gaearon/native-tree-devtool

Make ReactComponentTreeDevtool work with React Native
This commit is contained in:
Dan Abramov
2016-04-29 16:20:58 +01:00
6 changed files with 1754 additions and 2 deletions
@@ -93,6 +93,8 @@ describe('ReactComponentTreeDevtool', () => {
return getTree(rootInstance._debugID, options).children[0];
}
// Mount once, render updates, then unmount.
// Ensure the tree is correct on every step.
pairs.forEach(([element, expectedTree]) => {
currentElement = element;
ReactDOM.render(<Wrapper />, node);
@@ -101,17 +103,17 @@ describe('ReactComponentTreeDevtool', () => {
expect(getActualTree()).toEqual(expectedTree);
});
ReactDOM.unmountComponentAtNode(node);
ReactComponentTreeDevtool.purgeUnmountedComponents();
expect(getActualTree()).toBe(undefined);
expect(getRootDisplayNames()).toEqual([]);
expect(getRegisteredDisplayNames()).toEqual([]);
// Server render every pair.
// Ensure the tree is correct on every step.
pairs.forEach(([element, expectedTree]) => {
currentElement = element;
ReactDOMServer.renderToString(<Wrapper />);
expect(getActualTree()).toEqual(expectedTree);
ReactComponentTreeDevtool.purgeUnmountedComponents();
expect(getActualTree()).toBe(undefined);
expect(getRootDisplayNames()).toEqual([]);
File diff suppressed because it is too large Load Diff
@@ -12,6 +12,7 @@
'use strict';
var ReactElement = require('ReactElement');
var ReactInstrumentation = require('ReactInstrumentation');
var ReactNativeContainerInfo = require('ReactNativeContainerInfo');
var ReactNativeTagHandles = require('ReactNativeTagHandles');
var ReactPerf = require('ReactPerf');
@@ -138,6 +139,12 @@ var ReactNativeMount = {
var instance = instantiateReactComponent(nextWrappedElement);
ReactNativeMount._instancesByContainerID[containerTag] = instance;
if (__DEV__) {
// Mute future events from the top level wrapper.
// It is an implementation detail that devtools should not know about.
instance._debugID = 0;
}
// The initial render is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidMount, will be batched
// according to the current batching strategy.
@@ -147,6 +154,12 @@ var ReactNativeMount = {
instance,
containerTag
);
if (__DEV__) {
// The instance here is TopLevelWrapper so we report mount for its child.
ReactInstrumentation.debugTool.onMountRootComponent(
instance._renderedComponent._debugID
);
}
var component = instance.getPublicInstance();
if (callback) {
callback.call(component);
@@ -11,6 +11,7 @@
'use strict';
var ReactInstrumentation = require('ReactInstrumentation');
var ReactNativeComponentTree = require('ReactNativeComponentTree');
var ReactNativeTagHandles = require('ReactNativeTagHandles');
var UIManager = require('UIManager');
@@ -28,6 +29,10 @@ var ReactNativeTextComponent = function(text) {
Object.assign(ReactNativeTextComponent.prototype, {
mountComponent: function(transaction, nativeParent, nativeContainerInfo, context) {
if (__DEV__) {
ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);
}
// TODO: nativeParent should have this context already. Stop abusing context.
invariant(
context.isInAParentText,
@@ -65,6 +70,12 @@ Object.assign(ReactNativeTextComponent.prototype, {
'RCTRawText',
{text: this._stringText}
);
if (__DEV__) {
ReactInstrumentation.debugTool.onSetText(
this._debugID,
nextStringText
);
}
}
}
},
@@ -16,6 +16,8 @@ var RCTUIManager = {
setChildren: jest.fn(),
manageChildren: jest.fn(),
updateView: jest.fn(),
removeSubviewsFromContainerWithID: jest.fn(),
replaceExistingNonRootView: jest.fn(),
};
module.exports = RCTUIManager;
@@ -0,0 +1,19 @@
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
'use strict';
var createReactNativeComponentClass = require('createReactNativeComponentClass');
var View = createReactNativeComponentClass({
validAttributes: {},
uiViewClassName: 'View',
});
module.exports = View;