mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove unnecessary indirection and events from the hooks (#7464)
* Remove unnecessary indirection from the tree hook * Replace onSetDisplayName, onSetOwner, onSetText with one event Less events is better. onSetDisplayName, onSetOwner, and onSetText only existed because we didn't initially track elements. * Remove unused variables
This commit is contained in:
@@ -39,21 +39,16 @@ function remove(id) {
|
||||
delete itemByKey[key];
|
||||
}
|
||||
|
||||
function update(id, updater) {
|
||||
function create(id, element) {
|
||||
var key = getKeyFromID(id);
|
||||
if (!itemByKey[key]) {
|
||||
itemByKey[key] = {
|
||||
element: null,
|
||||
parentID: null,
|
||||
ownerID: null,
|
||||
text: null,
|
||||
childIDs: [],
|
||||
displayName: 'Unknown',
|
||||
isMounted: false,
|
||||
updateCount: 0,
|
||||
};
|
||||
}
|
||||
updater(itemByKey[key]);
|
||||
itemByKey[key] = {
|
||||
element,
|
||||
parentID: null,
|
||||
text: null,
|
||||
childIDs: [],
|
||||
isMounted: false,
|
||||
updateCount: 0,
|
||||
};
|
||||
}
|
||||
|
||||
function purgeDeep(id) {
|
||||
@@ -76,6 +71,18 @@ function describeComponentFrame(name, source, ownerName) {
|
||||
);
|
||||
}
|
||||
|
||||
function getDisplayName(element) {
|
||||
if (element == null) {
|
||||
return '#empty';
|
||||
} else if (typeof element === 'string' || typeof element === 'number') {
|
||||
return '#text';
|
||||
} else if (typeof element.type === 'string') {
|
||||
return element.type;
|
||||
} else {
|
||||
return element.type.displayName || element.type.name || 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
function describeID(id) {
|
||||
var name = ReactComponentTreeHook.getDisplayName(id);
|
||||
var element = ReactComponentTreeHook.getElement(id);
|
||||
@@ -94,76 +101,74 @@ function describeID(id) {
|
||||
}
|
||||
|
||||
var ReactComponentTreeHook = {
|
||||
onSetDisplayName(id, displayName) {
|
||||
update(id, item => item.displayName = displayName);
|
||||
},
|
||||
|
||||
onSetChildren(id, nextChildIDs) {
|
||||
update(id, item => {
|
||||
item.childIDs = nextChildIDs;
|
||||
var item = get(id);
|
||||
item.childIDs = nextChildIDs;
|
||||
|
||||
nextChildIDs.forEach(nextChildID => {
|
||||
var nextChild = get(nextChildID);
|
||||
invariant(
|
||||
nextChild,
|
||||
'Expected hook events 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 onSetChildren() or onSetText() to fire for the child ' +
|
||||
'before its parent includes it in onSetChildren().'
|
||||
);
|
||||
invariant(
|
||||
nextChild.isMounted,
|
||||
'Expected onMountComponent() to fire for the child ' +
|
||||
'before its parent includes it in onSetChildren().'
|
||||
);
|
||||
if (nextChild.parentID == null) {
|
||||
nextChild.parentID = id;
|
||||
// TODO: This shouldn't be necessary but mounting a new root during in
|
||||
// componentWillMount currently causes not-yet-mounted components to
|
||||
// be purged from our tree data so their parent ID is missing.
|
||||
}
|
||||
invariant(
|
||||
nextChild.parentID === id,
|
||||
'Expected onSetParent() and onSetChildren() to be consistent (%s ' +
|
||||
'has parents %s and %s).',
|
||||
nextChildID,
|
||||
nextChild.parentID,
|
||||
id
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
onSetOwner(id, ownerID) {
|
||||
update(id, item => item.ownerID = ownerID);
|
||||
for (var i = 0; i < nextChildIDs.length; i++) {
|
||||
var nextChildID = nextChildIDs[i];
|
||||
var nextChild = get(nextChildID);
|
||||
invariant(
|
||||
nextChild,
|
||||
'Expected hook events to fire for the child ' +
|
||||
'before its parent includes it in onSetChildren().'
|
||||
);
|
||||
invariant(
|
||||
nextChild.childIDs != null ||
|
||||
typeof nextChild.element !== 'object' ||
|
||||
nextChild.element == null,
|
||||
'Expected onSetChildren() to fire for a container child ' +
|
||||
'before its parent includes it in onSetChildren().'
|
||||
);
|
||||
invariant(
|
||||
nextChild.isMounted,
|
||||
'Expected onMountComponent() to fire for the child ' +
|
||||
'before its parent includes it in onSetChildren().'
|
||||
);
|
||||
if (nextChild.parentID == null) {
|
||||
nextChild.parentID = id;
|
||||
// TODO: This shouldn't be necessary but mounting a new root during in
|
||||
// componentWillMount currently causes not-yet-mounted components to
|
||||
// be purged from our tree data so their parent ID is missing.
|
||||
}
|
||||
invariant(
|
||||
nextChild.parentID === id,
|
||||
'Expected onSetParent() and onSetChildren() to be consistent (%s ' +
|
||||
'has parents %s and %s).',
|
||||
nextChildID,
|
||||
nextChild.parentID,
|
||||
id
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
onSetParent(id, parentID) {
|
||||
update(id, item => item.parentID = parentID);
|
||||
var item = get(id);
|
||||
item.parentID = parentID;
|
||||
},
|
||||
|
||||
onSetText(id, text) {
|
||||
update(id, item => item.text = text);
|
||||
onInstantiateComponent(id, element) {
|
||||
create(id, element);
|
||||
},
|
||||
|
||||
onBeforeMountComponent(id, element) {
|
||||
update(id, item => item.element = element);
|
||||
var item = get(id);
|
||||
item.element = element;
|
||||
},
|
||||
|
||||
onBeforeUpdateComponent(id, element) {
|
||||
update(id, item => item.element = element);
|
||||
var item = get(id);
|
||||
if (!item || !item.isMounted) {
|
||||
// We may end up here as a result of setState() in componentWillUnmount().
|
||||
// In this case, ignore the element.
|
||||
return;
|
||||
}
|
||||
item.element = element;
|
||||
},
|
||||
|
||||
onMountComponent(id) {
|
||||
update(id, item => item.isMounted = true);
|
||||
var item = get(id);
|
||||
item.isMounted = true;
|
||||
},
|
||||
|
||||
onMountRootComponent(id) {
|
||||
@@ -171,11 +176,18 @@ var ReactComponentTreeHook = {
|
||||
},
|
||||
|
||||
onUpdateComponent(id) {
|
||||
update(id, item => item.updateCount++);
|
||||
var item = get(id);
|
||||
if (!item || !item.isMounted) {
|
||||
// We may end up here as a result of setState() in componentWillUnmount().
|
||||
// In this case, ignore the element.
|
||||
return;
|
||||
}
|
||||
item.updateCount++;
|
||||
},
|
||||
|
||||
onUnmountComponent(id) {
|
||||
update(id, item => item.isMounted = false);
|
||||
var item = get(id);
|
||||
item.isMounted = false;
|
||||
unmountedIDs[id] = true;
|
||||
delete rootIDs[id];
|
||||
},
|
||||
@@ -234,8 +246,11 @@ var ReactComponentTreeHook = {
|
||||
},
|
||||
|
||||
getDisplayName(id) {
|
||||
var item = get(id);
|
||||
return item ? item.displayName : 'Unknown';
|
||||
var element = ReactComponentTreeHook.getElement(id);
|
||||
if (!element) {
|
||||
return null;
|
||||
}
|
||||
return getDisplayName(element);
|
||||
},
|
||||
|
||||
getElement(id) {
|
||||
@@ -244,8 +259,11 @@ var ReactComponentTreeHook = {
|
||||
},
|
||||
|
||||
getOwnerID(id) {
|
||||
var item = get(id);
|
||||
return item ? item.ownerID : null;
|
||||
var element = ReactComponentTreeHook.getElement(id);
|
||||
if (!element || !element._owner) {
|
||||
return null;
|
||||
}
|
||||
return element._owner._debugID;
|
||||
},
|
||||
|
||||
getParentID(id) {
|
||||
@@ -261,8 +279,14 @@ var ReactComponentTreeHook = {
|
||||
},
|
||||
|
||||
getText(id) {
|
||||
var item = get(id);
|
||||
return item ? item.text : null;
|
||||
var element = ReactComponentTreeHook.getElement(id);
|
||||
if (typeof element === 'string') {
|
||||
return element;
|
||||
} else if (typeof element === 'number') {
|
||||
return '' + element;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
getUpdateCount(id) {
|
||||
|
||||
@@ -270,16 +270,12 @@ if (__DEV__) {
|
||||
}
|
||||
|
||||
this._contentDebugID = contentDebugID;
|
||||
var text = '' + content;
|
||||
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(contentDebugID, '#text');
|
||||
ReactInstrumentation.debugTool.onSetParent(contentDebugID, debugID);
|
||||
ReactInstrumentation.debugTool.onSetText(contentDebugID, text);
|
||||
|
||||
if (hasExistingContent) {
|
||||
ReactInstrumentation.debugTool.onBeforeUpdateComponent(contentDebugID, content);
|
||||
ReactInstrumentation.debugTool.onUpdateComponent(contentDebugID);
|
||||
} else {
|
||||
ReactInstrumentation.debugTool.onInstantiateComponent(contentDebugID, content);
|
||||
ReactInstrumentation.debugTool.onSetParent(contentDebugID, debugID);
|
||||
ReactInstrumentation.debugTool.onBeforeMountComponent(contentDebugID, content);
|
||||
ReactInstrumentation.debugTool.onMountComponent(contentDebugID);
|
||||
ReactInstrumentation.debugTool.onSetChildren(debugID, [contentDebugID]);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
var DOMChildrenOperations = require('DOMChildrenOperations');
|
||||
var DOMLazyTree = require('DOMLazyTree');
|
||||
var ReactDOMComponentTree = require('ReactDOMComponentTree');
|
||||
var ReactInstrumentation = require('ReactInstrumentation');
|
||||
|
||||
var escapeTextContentForBrowser = require('escapeTextContentForBrowser');
|
||||
var invariant = require('invariant');
|
||||
@@ -67,8 +66,6 @@ Object.assign(ReactDOMTextComponent.prototype, {
|
||||
context
|
||||
) {
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);
|
||||
|
||||
var parentInfo;
|
||||
if (hostParent != null) {
|
||||
parentInfo = hostParent._ancestorInfo;
|
||||
@@ -142,13 +139,6 @@ Object.assign(ReactDOMTextComponent.prototype, {
|
||||
commentNodes[1],
|
||||
nextStringText
|
||||
);
|
||||
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onSetText(
|
||||
this._debugID,
|
||||
nextStringText
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
var ReactInstrumentation = require('ReactInstrumentation');
|
||||
var ReactNativeComponentTree = require('ReactNativeComponentTree');
|
||||
var ReactNativeTagHandles = require('ReactNativeTagHandles');
|
||||
var UIManager = require('UIManager');
|
||||
@@ -29,10 +28,6 @@ var ReactNativeTextComponent = function(text) {
|
||||
Object.assign(ReactNativeTextComponent.prototype, {
|
||||
|
||||
mountComponent: function(transaction, hostParent, hostContainerInfo, context) {
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onSetText(this._debugID, this._stringText);
|
||||
}
|
||||
|
||||
// TODO: hostParent should have this context already. Stop abusing context.
|
||||
invariant(
|
||||
context.isInAParentText,
|
||||
@@ -70,12 +65,6 @@ Object.assign(ReactNativeTextComponent.prototype, {
|
||||
'RCTRawText',
|
||||
{text: this._stringText}
|
||||
);
|
||||
if (__DEV__) {
|
||||
ReactInstrumentation.debugTool.onSetText(
|
||||
this._debugID,
|
||||
nextStringText
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -283,26 +283,18 @@ var ReactDebugTool = {
|
||||
onSetState() {
|
||||
emitEvent('onSetState');
|
||||
},
|
||||
onSetDisplayName(debugID, displayName) {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onSetDisplayName', debugID, displayName);
|
||||
},
|
||||
onSetChildren(debugID, childDebugIDs) {
|
||||
checkDebugID(debugID);
|
||||
childDebugIDs.forEach(checkDebugID);
|
||||
emitEvent('onSetChildren', debugID, childDebugIDs);
|
||||
},
|
||||
onSetOwner(debugID, ownerDebugID) {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onSetOwner', debugID, ownerDebugID);
|
||||
},
|
||||
onSetParent(debugID, parentDebugID) {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onSetParent', debugID, parentDebugID);
|
||||
},
|
||||
onSetText(debugID, text) {
|
||||
onInstantiateComponent(debugID, element) {
|
||||
checkDebugID(debugID);
|
||||
emitEvent('onSetText', debugID, text);
|
||||
emitEvent('onInstantiateComponent', debugID, element);
|
||||
},
|
||||
onMountRootComponent(debugID) {
|
||||
checkDebugID(debugID);
|
||||
|
||||
@@ -41,21 +41,6 @@ function getDeclarationErrorAddendum(owner) {
|
||||
return '';
|
||||
}
|
||||
|
||||
function getDisplayName(instance) {
|
||||
var element = instance._currentElement;
|
||||
if (element == null) {
|
||||
return '#empty';
|
||||
} else if (typeof element === 'string' || typeof element === 'number') {
|
||||
return '#text';
|
||||
} else if (typeof element.type === 'string') {
|
||||
return element.type;
|
||||
} else if (instance.getName) {
|
||||
return instance.getName() || 'Unknown';
|
||||
} else {
|
||||
return element.type.displayName || element.type.name || 'Unknown';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the type reference is a known internal type. I.e. not a user
|
||||
* provided composite type.
|
||||
@@ -144,12 +129,7 @@ function instantiateReactComponent(node, shouldHaveDebugID) {
|
||||
if (shouldHaveDebugID) {
|
||||
var debugID = nextDebugID++;
|
||||
instance._debugID = debugID;
|
||||
var displayName = getDisplayName(instance);
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(debugID, displayName);
|
||||
var owner = node && node._owner;
|
||||
if (owner) {
|
||||
ReactInstrumentation.debugTool.onSetOwner(debugID, owner._debugID);
|
||||
}
|
||||
ReactInstrumentation.debugTool.onInstantiateComponent(debugID, node);
|
||||
} else {
|
||||
instance._debugID = 0;
|
||||
}
|
||||
|
||||
@@ -384,6 +384,7 @@ var NoopInternalComponent = function(element) {
|
||||
this._renderedOutput = element;
|
||||
this._currentElement = element;
|
||||
this._debugID = nextDebugID++;
|
||||
ReactInstrumentation.debugTool.onInstantiateComponent(this._debugID, element);
|
||||
};
|
||||
|
||||
NoopInternalComponent.prototype = {
|
||||
@@ -412,8 +413,7 @@ var ShallowComponentWrapper = function(element) {
|
||||
// TODO: Consolidate with instantiateReactComponent
|
||||
if (__DEV__) {
|
||||
this._debugID = nextDebugID++;
|
||||
var displayName = element.type.displayName || element.type.name || 'Unknown';
|
||||
ReactInstrumentation.debugTool.onSetDisplayName(this._debugID, displayName);
|
||||
ReactInstrumentation.debugTool.onInstantiateComponent(this._debugID, element);
|
||||
}
|
||||
|
||||
this.construct(element);
|
||||
|
||||
Reference in New Issue
Block a user