diff --git a/src/isomorphic/classic/element/ReactDebugCurrentFrame.js b/src/isomorphic/classic/element/ReactDebugCurrentFrame.js index f4efdd672b..9cfbab11c4 100644 --- a/src/isomorphic/classic/element/ReactDebugCurrentFrame.js +++ b/src/isomorphic/classic/element/ReactDebugCurrentFrame.js @@ -18,12 +18,7 @@ import type { DebugID } from 'ReactInstanceType'; const ReactDebugCurrentFrame = {}; if (__DEV__) { - var { - getStackAddendumByID, - getStackAddendumByWorkInProgressFiber, - getCurrentStackAddendum, - } = require('ReactComponentTreeHook'); - + var ReactComponentTreeHook = require('ReactComponentTreeHook'); // Component that is being worked on ReactDebugCurrentFrame.current = (null : Fiber | DebugID | null); @@ -38,16 +33,16 @@ if (__DEV__) { if (typeof current === 'number') { // DebugID from Stack. const debugID = current; - stack = getStackAddendumByID(debugID); + stack = (ReactComponentTreeHook: any).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 = getStackAddendumByWorkInProgressFiber(workInProgress); + stack = ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress); } } else if (element !== null) { - stack = getCurrentStackAddendum(element); + stack = (ReactComponentTreeHook: any).getCurrentStackAddendum(element); } return stack; }; diff --git a/src/isomorphic/hooks/ReactComponentTreeHook.js b/src/isomorphic/hooks/ReactComponentTreeHook.js index 2359fd1c34..40c9a50279 100644 --- a/src/isomorphic/hooks/ReactComponentTreeHook.js +++ b/src/isomorphic/hooks/ReactComponentTreeHook.js @@ -12,7 +12,11 @@ 'use strict'; -var ReactCurrentOwner = require('ReactCurrentOwner'); +import type { ReactElement, Source } from 'ReactElementType'; +import type { DebugID } from 'ReactInstanceType'; +import type { Fiber } from 'ReactFiber'; + +var getComponentName = require('getComponentName'); var ReactTypeOfWork = require('ReactTypeOfWork'); var { IndeterminateComponent, @@ -21,144 +25,6 @@ var { HostComponent, } = ReactTypeOfWork; -var getComponentName = require('getComponentName'); -var invariant = require('fbjs/lib/invariant'); -var warning = require('fbjs/lib/warning'); - -import type { ReactElement, Source } from 'ReactElementType'; -import type { DebugID } from 'ReactInstanceType'; -import type { Fiber } from 'ReactFiber'; - -function isNative(fn) { - // Based on isNative() from Lodash - var funcToString = Function.prototype.toString; - var hasOwnProperty = Object.prototype.hasOwnProperty; - var reIsNative = RegExp('^' + funcToString - // Take an example native function source for comparison - .call(hasOwnProperty) - // Strip regex characters so we can use it for regex - .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') - // Remove hasOwnProperty from the template to make it generic - .replace( - /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, - '$1.*?' - ) + '$' - ); - try { - var source = funcToString.call(fn); - return reIsNative.test(source); - } catch (err) { - return false; - } -} - -var canUseCollections = ( - // Array.from - typeof Array.from === 'function' && - // Map - typeof Map === 'function' && - isNative(Map) && - // Map.prototype.keys - Map.prototype != null && - typeof Map.prototype.keys === 'function' && - isNative(Map.prototype.keys) && - // Set - typeof Set === 'function' && - isNative(Set) && - // Set.prototype.keys - Set.prototype != null && - typeof Set.prototype.keys === 'function' && - isNative(Set.prototype.keys) -); - -var setItem; -var getItem; -var removeItem; -var getItemIDs; -var addRoot; -var removeRoot; -var getRootIDs; - -if (canUseCollections) { - var itemMap = new Map(); - var rootIDSet = new Set(); - - setItem = function(id, item) { - itemMap.set(id, item); - }; - getItem = function(id) { - return itemMap.get(id); - }; - removeItem = function(id) { - itemMap.delete(id); - }; - getItemIDs = function() { - return Array.from(itemMap.keys()); - }; - - addRoot = function(id) { - rootIDSet.add(id); - }; - removeRoot = function(id) { - rootIDSet.delete(id); - }; - getRootIDs = function() { - return Array.from(rootIDSet.keys()); - }; - -} else { - var itemByKey = {}; - var rootByKey = {}; - - // Use non-numeric keys to prevent V8 performance issues: - // https://github.com/facebook/react/pull/7232 - var getKeyFromID = function(id: DebugID): string { - return '.' + id; - }; - var getIDFromKey = function(key: string): DebugID { - return parseInt(key.substr(1), 10); - }; - - setItem = function(id, item) { - var key = getKeyFromID(id); - itemByKey[key] = item; - }; - getItem = function(id) { - var key = getKeyFromID(id); - return itemByKey[key]; - }; - removeItem = function(id) { - var key = getKeyFromID(id); - delete itemByKey[key]; - }; - getItemIDs = function() { - return Object.keys(itemByKey).map(getIDFromKey); - }; - - addRoot = function(id) { - var key = getKeyFromID(id); - rootByKey[key] = true; - }; - removeRoot = function(id) { - var key = getKeyFromID(id); - delete rootByKey[key]; - }; - getRootIDs = function() { - return Object.keys(rootByKey).map(getIDFromKey); - }; -} - -var unmountedIDs: Array = []; - -function purgeDeep(id) { - var item = getItem(id); - if (item) { - var {childIDs} = item; - removeItem(id); - childIDs.forEach(purgeDeep); - } -} - function describeComponentFrame(name, source, ownerName) { return '\n in ' + (name || 'Unknown') + ( source ? @@ -170,35 +36,6 @@ function describeComponentFrame(name, source, ownerName) { ); } -function getDisplayName(element: ?ReactElement): string { - 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: DebugID): string { - var name = ReactComponentTreeHook.getDisplayName(id); - var element = ReactComponentTreeHook.getElement(id); - var ownerID = ReactComponentTreeHook.getOwnerID(id); - var ownerName; - if (ownerID) { - ownerName = ReactComponentTreeHook.getDisplayName(ownerID); - } - warning( - element, - 'ReactComponentTreeHook: Missing React element for debugID %s when ' + - 'building stack', - id - ); - return describeComponentFrame(name, element && element._source, ownerName); -} - function describeFiber(fiber : Fiber) : string { switch (fiber.tag) { case IndeterminateComponent: @@ -219,160 +56,6 @@ function describeFiber(fiber : Fiber) : string { } var ReactComponentTreeHook = { - onSetChildren(id: DebugID, nextChildIDs: Array): void { - var item = getItem(id); - invariant(item, 'Item must have been set'); - item.childIDs = nextChildIDs; - - for (var i = 0; i < nextChildIDs.length; i++) { - var nextChildID = nextChildIDs[i]; - var nextChild = getItem(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 onBeforeMountComponent() parent and onSetChildren() to ' + - 'be consistent (%s has parents %s and %s).', - nextChildID, - nextChild.parentID, - id - ); - } - }, - - onBeforeMountComponent(id: DebugID, element: ReactElement, parentID: DebugID): void { - var item = { - element, - parentID, - text: null, - childIDs: [], - isMounted: false, - updateCount: 0, - }; - setItem(id, item); - }, - - onBeforeUpdateComponent(id: DebugID, element: ReactElement): void { - var item = getItem(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: DebugID): void { - var item = getItem(id); - invariant(item, 'Item must have been set'); - item.isMounted = true; - var isRoot = item.parentID === 0; - if (isRoot) { - addRoot(id); - } - }, - - onUpdateComponent(id: DebugID): void { - var item = getItem(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: DebugID): void { - var item = getItem(id); - if (item) { - // We need to check if it exists. - // `item` might not exist if it is inside an error boundary, and a sibling - // error boundary child threw while mounting. Then this instance never - // got a chance to mount, but it still gets an unmounting event during - // the error boundary cleanup. - item.isMounted = false; - var isRoot = item.parentID === 0; - if (isRoot) { - removeRoot(id); - } - } - unmountedIDs.push(id); - }, - - purgeUnmountedComponents(): void { - if (ReactComponentTreeHook._preventPurging) { - // Should only be used for testing. - return; - } - - for (var i = 0; i < unmountedIDs.length; i++) { - var id = unmountedIDs[i]; - purgeDeep(id); - } - unmountedIDs.length = 0; - }, - - isMounted(id: DebugID): boolean { - var item = getItem(id); - return item ? item.isMounted : false; - }, - - getCurrentStackAddendum(topElement: ?ReactElement): string { - var info = ''; - if (topElement) { - var name = getDisplayName(topElement); - var owner = topElement._owner; - info += describeComponentFrame( - name, - topElement._source, - owner && getComponentName(owner) - ); - } - - var currentOwner = ReactCurrentOwner.current; - if (currentOwner) { - if (typeof currentOwner.tag === 'number') { - const workInProgress = ((currentOwner : any) : Fiber); - // Safe because if current owner exists, we are reconciling, - // and it is guaranteed to be the work-in-progress version. - info += ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress); - } else if (typeof currentOwner._debugID === 'number') { - info += ReactComponentTreeHook.getStackAddendumByID(currentOwner._debugID); - } - } - return info; - }, - - getStackAddendumByID(id: ?DebugID): string { - var info = ''; - while (id) { - info += describeID(id); - id = ReactComponentTreeHook.getParentID(id); - } - return info; - }, - // 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. @@ -386,63 +69,392 @@ var ReactComponentTreeHook = { } while (node); return info; }, +}; - getChildIDs(id: DebugID): Array { - var item = getItem(id); - return item ? item.childIDs : []; - }, +if (__DEV__) { + var ReactCurrentOwner = require('ReactCurrentOwner'); + var invariant = require('fbjs/lib/invariant'); + var warning = require('fbjs/lib/warning'); - getDisplayName(id: DebugID): ?string { - var element = ReactComponentTreeHook.getElement(id); - if (!element) { - return null; + var isNative = function(fn) { + // Based on isNative() from Lodash + var funcToString = Function.prototype.toString; + var hasOwnProperty = Object.prototype.hasOwnProperty; + var reIsNative = RegExp('^' + funcToString + // Take an example native function source for comparison + .call(hasOwnProperty) + // Strip regex characters so we can use it for regex + .replace(/[\\^$.*+?()[\]{}|]/g, '\\$&') + // Remove hasOwnProperty from the template to make it generic + .replace( + /hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, + '$1.*?' + ) + '$' + ); + try { + var source = funcToString.call(fn); + return reIsNative.test(source); + } catch (err) { + return false; } - return getDisplayName(element); - }, + }; - getElement(id: DebugID): ?ReactElement { + var canUseCollections = ( + // Array.from + typeof Array.from === 'function' && + // Map + typeof Map === 'function' && + isNative(Map) && + // Map.prototype.keys + Map.prototype != null && + typeof Map.prototype.keys === 'function' && + isNative(Map.prototype.keys) && + // Set + typeof Set === 'function' && + isNative(Set) && + // Set.prototype.keys + Set.prototype != null && + typeof Set.prototype.keys === 'function' && + isNative(Set.prototype.keys) + ); + + var setItem; + var getItem; + var removeItem; + var getItemIDs; + var addRoot; + var removeRoot; + var getRootIDs; + + if (canUseCollections) { + var itemMap = new Map(); + var rootIDSet = new Set(); + + setItem = function(id, item) { + itemMap.set(id, item); + }; + getItem = function(id) { + return itemMap.get(id); + }; + removeItem = function(id) { + itemMap.delete(id); + }; + getItemIDs = function() { + return Array.from(itemMap.keys()); + }; + + addRoot = function(id) { + rootIDSet.add(id); + }; + removeRoot = function(id) { + rootIDSet.delete(id); + }; + getRootIDs = function() { + return Array.from(rootIDSet.keys()); + }; + + } else { + var itemByKey = {}; + var rootByKey = {}; + + // Use non-numeric keys to prevent V8 performance issues: + // https://github.com/facebook/react/pull/7232 + var getKeyFromID = function(id: DebugID): string { + return '.' + id; + }; + var getIDFromKey = function(key: string): DebugID { + return parseInt(key.substr(1), 10); + }; + + setItem = function(id, item) { + var key = getKeyFromID(id); + itemByKey[key] = item; + }; + getItem = function(id) { + var key = getKeyFromID(id); + return itemByKey[key]; + }; + removeItem = function(id) { + var key = getKeyFromID(id); + delete itemByKey[key]; + }; + getItemIDs = function() { + return Object.keys(itemByKey).map(getIDFromKey); + }; + + addRoot = function(id) { + var key = getKeyFromID(id); + rootByKey[key] = true; + }; + removeRoot = function(id) { + var key = getKeyFromID(id); + delete rootByKey[key]; + }; + getRootIDs = function() { + return Object.keys(rootByKey).map(getIDFromKey); + }; + } + + var unmountedIDs: Array = []; + + var purgeDeep = function(id) { var item = getItem(id); - return item ? item.element : null; - }, + if (item) { + var {childIDs} = item; + removeItem(id); + childIDs.forEach(purgeDeep); + } + }; - getOwnerID(id: DebugID): ?DebugID { - var element = ReactComponentTreeHook.getElement(id); + var getDisplayName = function(element: ?ReactElement): string { + 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'; + } + }; + + var describeID = function(id: DebugID): string { + var name = getDisplayName((id: any)); + var element = getElement(id); + var ownerID: any = getOwnerID(id); + var ownerName; + if (ownerID) { + ownerName = getDisplayName(ownerID); + } + warning( + element, + 'ReactComponentTreeHook: Missing React element for debugID %s when ' + + 'building stack', + id + ); + 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; - }, + }; - getParentID(id: DebugID): ?DebugID { + var getElement = function(id: DebugID): ?ReactElement { + var item = getItem(id); + return item ? item.element : null; + }; + + var getParentID = function(id: DebugID): ?DebugID { var item = getItem(id); return item ? item.parentID : null; - }, - - getSource(id: DebugID): ?Source { - var item = getItem(id); - var element = item ? item.element : null; - var source = element != null ? element._source : null; - return source; - }, - - getText(id: DebugID): ?string { - var element = ReactComponentTreeHook.getElement(id); - if (typeof element === 'string') { - return element; - } else if (typeof element === 'number') { - return '' + element; - } else { - return null; + }; + + var getStackAddendumByID = function(id: ?DebugID): string { + var info = ''; + while (id) { + info += describeID(id); + id = getParentID(id); } - }, + return info; + }; - getUpdateCount(id: DebugID): number { - var item = getItem(id); - return item ? item.updateCount : 0; - }, + ReactComponentTreeHook = Object.assign({}, ReactComponentTreeHook, { + onSetChildren(id: DebugID, nextChildIDs: Array): void { + var item = getItem(id); + invariant(item, 'Item must have been set'); + item.childIDs = nextChildIDs; - getRootIDs, - getRegisteredIDs: getItemIDs, -}; + for (var i = 0; i < nextChildIDs.length; i++) { + var nextChildID = nextChildIDs[i]; + var nextChild = getItem(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 onBeforeMountComponent() parent and onSetChildren() to ' + + 'be consistent (%s has parents %s and %s).', + nextChildID, + nextChild.parentID, + id + ); + } + }, + + onBeforeMountComponent(id: DebugID, element: ReactElement, parentID: DebugID): void { + var item = { + element, + parentID, + text: null, + childIDs: [], + isMounted: false, + updateCount: 0, + }; + setItem(id, item); + }, + + onBeforeUpdateComponent(id: DebugID, element: ReactElement): void { + var item = getItem(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: DebugID): void { + var item = getItem(id); + invariant(item, 'Item must have been set'); + item.isMounted = true; + var isRoot = item.parentID === 0; + if (isRoot) { + addRoot(id); + } + }, + + onUpdateComponent(id: DebugID): void { + var item = getItem(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: DebugID): void { + var item = getItem(id); + if (item) { + // We need to check if it exists. + // `item` might not exist if it is inside an error boundary, and a sibling + // error boundary child threw while mounting. Then this instance never + // got a chance to mount, but it still gets an unmounting event during + // the error boundary cleanup. + item.isMounted = false; + var isRoot = item.parentID === 0; + if (isRoot) { + removeRoot(id); + } + } + unmountedIDs.push(id); + }, + + purgeUnmountedComponents(): void { + if (ReactComponentTreeHook._preventPurging) { + // Should only be used for testing. + return; + } + + for (var i = 0; i < unmountedIDs.length; i++) { + var id = unmountedIDs[i]; + purgeDeep(id); + } + unmountedIDs.length = 0; + }, + + isMounted(id: DebugID): boolean { + var item = getItem(id); + return item ? item.isMounted : false; + }, + + getCurrentStackAddendum(topElement: ?ReactElement): string { + var info = ''; + if (topElement) { + var name = getDisplayName(topElement); + var owner = topElement._owner; + info += describeComponentFrame( + name, + topElement._source, + owner && getComponentName(owner) + ); + } + + var currentOwner = ReactCurrentOwner.current; + if (currentOwner) { + if (typeof currentOwner.tag === 'number') { + const workInProgress = ((currentOwner : any) : Fiber); + // Safe because if current owner exists, we are reconciling, + // and it is guaranteed to be the work-in-progress version. + info += ReactComponentTreeHook.getStackAddendumByWorkInProgressFiber(workInProgress); + } else if (typeof currentOwner._debugID === 'number') { + info += getStackAddendumByID(currentOwner._debugID); + } + } + return info; + }, + + getStackAddendumByID, + + getChildIDs(id: DebugID): Array { + var item = getItem(id); + return item ? item.childIDs : []; + }, + + getDisplayName(id: DebugID): ?string { + var element = getElement(id); + if (!element) { + return null; + } + return getDisplayName(element); + }, + + getElement, + + getOwnerID, + + getParentID, + + getSource(id: DebugID): ?Source { + var item = getItem(id); + var element = item ? item.element : null; + var source = element != null ? element._source : null; + return source; + }, + + getText(id: DebugID): ?string { + var element = getElement(id); + if (typeof element === 'string') { + return element; + } else if (typeof element === 'number') { + return '' + element; + } else { + return null; + } + }, + + getUpdateCount(id: DebugID): number { + var item = getItem(id); + return item ? item.updateCount : 0; + }, + + getRootIDs, + getRegisteredIDs: getItemIDs, + }); +} module.exports = ReactComponentTreeHook; diff --git a/src/renderers/shared/ReactDebugTool.js b/src/renderers/shared/ReactDebugTool.js index 6a3781f947..bae00db165 100644 --- a/src/renderers/shared/ReactDebugTool.js +++ b/src/renderers/shared/ReactDebugTool.js @@ -108,22 +108,22 @@ if (__DEV__) { var lifeCycleTimerHasWarned = false; const clearHistory = function() { - ReactComponentTreeHook.purgeUnmountedComponents(); + (ReactComponentTreeHook: any).purgeUnmountedComponents(); ReactHostOperationHistoryHook.clearHistory(); }; const getTreeSnapshot = function(registeredIDs) { return registeredIDs.reduce((tree, id) => { - var ownerID = ReactComponentTreeHook.getOwnerID(id); - var parentID = ReactComponentTreeHook.getParentID(id); + var ownerID = (ReactComponentTreeHook: any).getOwnerID(id); + var parentID = (ReactComponentTreeHook: any).getParentID(id); tree[id] = { - displayName: ReactComponentTreeHook.getDisplayName(id), - text: ReactComponentTreeHook.getText(id), - updateCount: ReactComponentTreeHook.getUpdateCount(id), - childIDs: ReactComponentTreeHook.getChildIDs(id), + displayName: (ReactComponentTreeHook: any).getDisplayName(id), + text: (ReactComponentTreeHook: any).getText(id), + updateCount: (ReactComponentTreeHook: any).getUpdateCount(id), + childIDs: (ReactComponentTreeHook: any).getChildIDs(id), // Text nodes don't have owners but this is close enough. ownerID: ownerID || - parentID && ReactComponentTreeHook.getOwnerID(parentID) || + parentID && (ReactComponentTreeHook: any).getOwnerID(parentID) || 0, parentID, }; @@ -144,7 +144,7 @@ if (__DEV__) { } if (previousMeasurements.length || previousOperations.length) { - var registeredIDs = ReactComponentTreeHook.getRegisteredIDs(); + var registeredIDs = (ReactComponentTreeHook: any).getRegisteredIDs(); flushHistory.push({ duration: performanceNow() - previousStartTime, measurements: previousMeasurements || [], @@ -253,7 +253,7 @@ if (__DEV__) { if (!isProfiling || !canUsePerformanceMeasure) { return false; } - var element = ReactComponentTreeHook.getElement(debugID); + var element = (ReactComponentTreeHook: any).getElement(debugID); if (element == null || typeof element !== 'object') { return false; } @@ -280,7 +280,7 @@ if (__DEV__) { } var markName = `${debugID}::${markType}`; - var displayName = ReactComponentTreeHook.getDisplayName(debugID) || 'Unknown'; + var displayName = (ReactComponentTreeHook: any).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 120c6dddbd..1a088e32da 100644 --- a/src/renderers/shared/stack/reconciler/ReactRef.js +++ b/src/renderers/shared/stack/reconciler/ReactRef.js @@ -53,7 +53,7 @@ function attachRef(ref, component, owner) { 'Stateless function components cannot be given refs. ' + 'Attempts to access this ref will fail.%s%s', info, - ReactComponentTreeHook.getStackAddendumByID(component._debugID) + (ReactComponentTreeHook: any).getStackAddendumByID(component._debugID) ); } } diff --git a/src/shared/utils/flattenChildren.js b/src/shared/utils/flattenChildren.js index d07630580f..7bc7d7c94a 100644 --- a/src/shared/utils/flattenChildren.js +++ b/src/shared/utils/flattenChildren.js @@ -58,7 +58,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.getStackAddendumByID(selfDebugID) + (ReactComponentTreeHook: any).getStackAddendumByID(selfDebugID) ); } }