@@ -26,6 +26,7 @@ import {
2626 ContextProvider ,
2727 ForwardRef ,
2828} from 'react-reconciler/src/ReactWorkTags' ;
29+ import { REACT_MEMO_CACHE_SENTINEL } from 'shared/ReactSymbols' ;
2930
3031type CurrentDispatcherRef = typeof ReactSharedInternals . ReactCurrentDispatcher ;
3132
@@ -93,7 +94,9 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
9394 return primitiveStackCache ;
9495}
9596
97+ let currentFiber : null | Fiber = null ;
9698let currentHook : null | Hook = null ;
99+
97100function nextHook ( ) : null | Hook {
98101 const hook = currentHook ;
99102 if ( hook !== null ) {
@@ -319,9 +322,31 @@ function useId(): string {
319322
320323// useMemoCache is an implementation detail of Forget's memoization
321324// it should not be called directly in user-generated code
322- // we keep it as a stub for dispatcher
323325function useMemoCache(size: number): Array< any > {
324- return [ ] ;
326+ const fiber = currentFiber ;
327+ // Don't throw, in case this is called from getPrimitiveStackCache
328+ if ( fiber == null ) {
329+ return [ ] ;
330+ }
331+
332+ // $FlowFixMe[incompatible-use]: updateQueue is mixed
333+ const memoCache = fiber.updateQueue?.memoCache;
334+ if (memoCache == null) {
335+ return [ ] ;
336+ }
337+
338+ let data = memoCache.data[memoCache.index];
339+ if (data === undefined) {
340+ data = memoCache . data [ memoCache . index ] = new Array ( size ) ;
341+ for ( let i = 0 ; i < size ; i ++ ) {
342+ data [ i ] = REACT_MEMO_CACHE_SENTINEL ;
343+ }
344+ }
345+
346+ // We don't write anything to hookLog on purpose, so this hook remains invisible to users.
347+
348+ memoCache . index ++ ;
349+ return data ;
325350}
326351
327352const Dispatcher : DispatcherType = {
@@ -699,9 +724,11 @@ export function inspectHooks<Props>(
699724 }
700725
701726 const previousDispatcher = currentDispatcher.current;
702- let readHookLog;
703727 currentDispatcher.current = DispatcherProxy;
728+
729+ let readHookLog;
704730 let ancestorStackError;
731+
705732 try {
706733 ancestorStackError = new Error ( ) ;
707734 renderFunction ( props ) ;
@@ -798,19 +825,25 @@ export function inspectHooksOfFiber(
798825 'Unknown Fiber. Needs to be a function component to inspect hooks.' ,
799826 ) ;
800827 }
828+
829+ // Set up the current hook so that we can step through and read the
830+ // current state from them.
831+ currentHook = (fiber.memoizedState: Hook);
832+ currentFiber = fiber;
833+
801834 // Warm up the cache so that it doesn't consume the currentHook.
802835 getPrimitiveStackCache();
836+
803837 const type = fiber.type;
804838 let props = fiber.memoizedProps;
805839 if (type !== fiber.elementType) {
806840 props = resolveDefaultProps ( type , props ) ;
807841 }
808- // Set up the current hook so that we can step through and read the
809- // current state from them.
810- currentHook = (fiber.memoizedState: Hook);
811- const contextMap = new Map< ReactContext < $FlowFixMe > , $FlowFixMe> ( ) ;
842+
843+ const contextMap = new Map< ReactContext < any > , any> ( ) ;
812844 try {
813845 setupContexts ( contextMap , fiber ) ;
846+
814847 if ( fiber . tag === ForwardRef ) {
815848 return inspectHooksOfForwardRef (
816849 type . render ,
@@ -820,9 +853,12 @@ export function inspectHooksOfFiber(
820853 includeHooksSource ,
821854 ) ;
822855 }
856+
823857 return inspectHooks(type, props, currentDispatcher, includeHooksSource);
824858 } finally {
859+ currentFiber = null ;
825860 currentHook = null ;
861+
826862 restoreContexts ( contextMap ) ;
827863 }
828864}
0 commit comments