diff --git a/src/isomorphic/classic/element/ReactDebugCurrentFrame.js b/src/isomorphic/classic/element/ReactDebugCurrentFrame.js index 9cfbab11c4..7a36e4f257 100644 --- a/src/isomorphic/classic/element/ReactDebugCurrentFrame.js +++ b/src/isomorphic/classic/element/ReactDebugCurrentFrame.js @@ -14,11 +14,16 @@ import type { Fiber } from 'ReactFiber'; import type { DebugID } from 'ReactInstanceType'; +import type { ComponentTreeHookType } from '../../hooks/ReactComponentTreeHook'; const ReactDebugCurrentFrame = {}; if (__DEV__) { - var ReactComponentTreeHook = require('ReactComponentTreeHook'); + const { + getStackAddendumByID, + getStackAddendumByWorkInProgressFiber, + getCurrentStackAddendum, + }: ComponentTreeHookType = require('ReactComponentTreeHook'); // Component that is being worked on ReactDebugCurrentFrame.current = (null : Fiber | DebugID | null); @@ -33,16 +38,20 @@ if (__DEV__) { if (typeof current === 'number') { // DebugID from Stack. const debugID = current; - stack = (ReactComponentTreeHook: any).getStackAddendumByID(debugID); + if (getStackAddendumByID) { + stack = getStackAddendumByID(debugID); + } } else if (typeof current.tag === 'number') { // This is a Fiber. // The stack will only be correct if this is a work in progress // version and we're calling it during reconciliation. const workInProgress = current; - stack = ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress); + stack = getStackAddendumByWorkInProgressFiber(workInProgress); } } else if (element !== null) { - stack = (ReactComponentTreeHook: any).getCurrentStackAddendum(element); + if (getCurrentStackAddendum) { + stack = getCurrentStackAddendum(element); + } } return stack; }; diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index 40c9a50279..a268651098 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -55,7 +55,21 @@ function describeFiber(fiber : Fiber) : string { } } -var ReactComponentTreeHook = { +export type ComponentTreeHookType = { + getStackAddendumByWorkInProgressFiber: (Fiber) => any, + getStackAddendumByID?: () => any, + getCurrentStackAddendum?: () => any, + purgeUnmountedComponents?: () => any, + getOwnerID?: (DebugID) => any, + getParentID?: (DebugID) => any, + getDisplayName?: (DebugID) => any, + getText?: (DebugID) => any, + getUpdateCount?: (DebugID) => any, + getChildIDs?: (DebugID) => any, + getRegisteredIDs?: () => any, +}; + +var ReactComponentTreeHook: ComponentTreeHookType = { // This function can only be called with a work-in-progress fiber and // only during begin or complete phase. Do not call it under any other // circumstances. @@ -195,9 +209,9 @@ if (__DEV__) { }; } - var unmountedIDs: Array = []; + const unmountedIDs: Array = []; - var purgeDeep = function(id) { + const purgeDeep = function(id) { var item = getItem(id); if (item) { var {childIDs} = item; @@ -206,7 +220,7 @@ if (__DEV__) { } }; - var getDisplayName = function(element: ?ReactElement): string { + const getDisplayNameFromElement = function(element: ?ReactElement): string { if (element == null) { return '#empty'; } else if (typeof element === 'string' || typeof element === 'number') { @@ -218,10 +232,26 @@ if (__DEV__) { } }; - var describeID = function(id: DebugID): string { - var name = getDisplayName((id: any)); + const getDisplayName = function(id: DebugID): ?string { var element = getElement(id); - var ownerID: any = getOwnerID(id); + if (!element) { + return null; + } + return getDisplayNameFromElement(element); + }; + + const getOwnerID = function(id: DebugID): ?DebugID { + var element = getElement(id); + if (!element || !element._owner) { + return null; + } + return element._owner._debugID; + }; + + const describeID = function(id: DebugID): string { + var name = getDisplayName(id); + var element = getElement(id); + var ownerID = getOwnerID(id); var ownerName; if (ownerID) { ownerName = getDisplayName(ownerID); @@ -235,25 +265,17 @@ if (__DEV__) { return describeComponentFrame(name, element && element._source, ownerName); }; - var getOwnerID = function(id: DebugID): ?DebugID { - var element = getElement(id); - if (!element || !element._owner) { - return null; - } - return element._owner._debugID; - }; - - var getElement = function(id: DebugID): ?ReactElement { + const getElement = function(id: DebugID): ?ReactElement { var item = getItem(id); return item ? item.element : null; }; - var getParentID = function(id: DebugID): ?DebugID { + const getParentID = function(id: DebugID): ?DebugID { var item = getItem(id); return item ? item.parentID : null; }; - - var getStackAddendumByID = function(id: ?DebugID): string { + + const getStackAddendumByID = function(id: ?DebugID): string { var info = ''; while (id) { info += describeID(id); @@ -385,7 +407,7 @@ if (__DEV__) { getCurrentStackAddendum(topElement: ?ReactElement): string { var info = ''; if (topElement) { - var name = getDisplayName(topElement); + var name = getDisplayNameFromElement(topElement); var owner = topElement._owner; info += describeComponentFrame( name, @@ -420,7 +442,7 @@ if (__DEV__) { if (!element) { return null; } - return getDisplayName(element); + return getDisplayNameFromElement(element); }, getElement, diff --git a/src/renderers/shared/ReactDebugTool.js b/src/renderers/shared/ReactDebugTool.js index bae00db165..1d07610ade 100644 --- a/src/renderers/shared/ReactDebugTool.js +++ b/src/renderers/shared/ReactDebugTool.js @@ -14,7 +14,6 @@ var ReactInvalidSetStateWarningHook = require('ReactInvalidSetStateWarningHook'); var ReactHostOperationHistoryHook = require('ReactHostOperationHistoryHook'); -var ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook'); var ExecutionEnvironment = require('fbjs/lib/ExecutionEnvironment'); var performanceNow = require('fbjs/lib/performanceNow'); @@ -67,8 +66,19 @@ export type FlushHistory = Array; var ReactDebugTool = ((null: any): typeof ReactDebugTool); if (__DEV__) { - var hooks = []; - var didHookThrowForEvent = {}; + const hooks = []; + const didHookThrowForEvent = {}; + const ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook'); + const { + purgeUnmountedComponents, + getOwnerID, + getParentID, + getDisplayName, + getText, + getUpdateCount, + getChildIDs, + getRegisteredIDs, + } = ReactComponentTreeHook; const callHook = function(event, fn, context, arg1, arg2, arg3, arg4, arg5) { try { @@ -108,22 +118,24 @@ if (__DEV__) { var lifeCycleTimerHasWarned = false; const clearHistory = function() { - (ReactComponentTreeHook: any).purgeUnmountedComponents(); + if (purgeUnmountedComponents) { + purgeUnmountedComponents(); + } ReactHostOperationHistoryHook.clearHistory(); }; const getTreeSnapshot = function(registeredIDs) { - return registeredIDs.reduce((tree, id) => { - var ownerID = (ReactComponentTreeHook: any).getOwnerID(id); - var parentID = (ReactComponentTreeHook: any).getParentID(id); + return registeredIDs && registeredIDs.reduce((tree, id) => { + var ownerID = getOwnerID && getOwnerID(id); + var parentID = getParentID && getParentID(id); tree[id] = { - displayName: (ReactComponentTreeHook: any).getDisplayName(id), - text: (ReactComponentTreeHook: any).getText(id), - updateCount: (ReactComponentTreeHook: any).getUpdateCount(id), - childIDs: (ReactComponentTreeHook: any).getChildIDs(id), + displayName: getDisplayName && getDisplayName(id), + text: getText && getText(id), + updateCount: getUpdateCount && getUpdateCount(id), + childIDs: getChildIDs && getChildIDs(id), // Text nodes don't have owners but this is close enough. ownerID: ownerID || - parentID && (ReactComponentTreeHook: any).getOwnerID(parentID) || + parentID && getOwnerID && getOwnerID(parentID) || 0, parentID, }; @@ -144,13 +156,16 @@ if (__DEV__) { } if (previousMeasurements.length || previousOperations.length) { - var registeredIDs = (ReactComponentTreeHook: any).getRegisteredIDs(); - flushHistory.push({ - duration: performanceNow() - previousStartTime, - measurements: previousMeasurements || [], - operations: previousOperations || [], - treeSnapshot: getTreeSnapshot(registeredIDs), - }); + var registeredIDs = getRegisteredIDs && getRegisteredIDs(); + + if (registeredIDs) { + flushHistory.push({ + duration: performanceNow() - previousStartTime, + measurements: previousMeasurements || [], + operations: previousOperations || [], + treeSnapshot: getTreeSnapshot(registeredIDs), + }); + } } clearHistory(); @@ -280,7 +295,7 @@ if (__DEV__) { } var markName = `${debugID}::${markType}`; - var displayName = (ReactComponentTreeHook: any).getDisplayName(debugID) || 'Unknown'; + var displayName = getDisplayName && getDisplayName(debugID) || 'Unknown'; // Chrome has an issue of dropping markers recorded too fast: // https://bugs.chromium.org/p/chromium/issues/detail?id=640652 diff --git a/src/renderers/shared/stack/reconciler/ReactRef.js b/src/renderers/shared/stack/reconciler/ReactRef.js index 1a088e32da..155dab6c80 100644 --- a/src/renderers/shared/stack/reconciler/ReactRef.js +++ b/src/renderers/shared/stack/reconciler/ReactRef.js @@ -21,7 +21,9 @@ var ReactRef = {}; if (__DEV__) { var ReactCompositeComponentTypes = require('ReactCompositeComponentTypes'); - var ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook'); + var { + getStackAddendumByID, + } = require('react/lib/ReactComponentTreeHook'); var warning = require('fbjs/lib/warning'); var warnedAboutStatelessRefs = {}; @@ -53,7 +55,7 @@ function attachRef(ref, component, owner) { 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, - (ReactComponentTreeHook: any).getStackAddendumByID(component._debugID) + getStackAddendumByID && getStackAddendumByID(component._debugID) ); } } diff --git a/src/shared/utils/flattenChildren.js b/src/shared/utils/flattenChildren.js index 7bc7d7c94a..f2992becdf 100644 --- a/src/shared/utils/flattenChildren.js +++ b/src/shared/utils/flattenChildren.js @@ -51,6 +51,8 @@ function flattenSingleChildIntoContext( if (!ReactComponentTreeHook) { ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook'); } + const { getStackAddendumByID } = ReactComponentTreeHook; + if (!keyUnique) { warning( false, @@ -58,7 +60,7 @@ function flattenSingleChildIntoContext( '`%s`. Child keys must be unique; when two children share a key, only ' + 'the first child will be used.%s', KeyEscapeUtils.unescape(name), - (ReactComponentTreeHook: any).getStackAddendumByID(selfDebugID) + getStackAddendumByID && getStackAddendumByID(selfDebugID) ); } }