@@ -26,6 +26,7 @@ import {
26
26
ContextProvider ,
27
27
ForwardRef ,
28
28
} from 'react-reconciler/src/ReactWorkTags' ;
29
+ import { REACT_MEMO_CACHE_SENTINEL } from 'shared/ReactSymbols' ;
29
30
30
31
type CurrentDispatcherRef = typeof ReactSharedInternals . ReactCurrentDispatcher ;
31
32
@@ -93,7 +94,9 @@ function getPrimitiveStackCache(): Map<string, Array<any>> {
93
94
return primitiveStackCache ;
94
95
}
95
96
97
+ let currentFiber : null | Fiber = null ;
96
98
let currentHook : null | Hook = null ;
99
+
97
100
function nextHook ( ) : null | Hook {
98
101
const hook = currentHook ;
99
102
if ( hook !== null ) {
@@ -319,9 +322,31 @@ function useId(): string {
319
322
320
323
// useMemoCache is an implementation detail of Forget's memoization
321
324
// it should not be called directly in user-generated code
322
- // we keep it as a stub for dispatcher
323
325
function 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 ;
325
350
}
326
351
327
352
const Dispatcher : DispatcherType = {
@@ -699,9 +724,11 @@ export function inspectHooks<Props>(
699
724
}
700
725
701
726
const previousDispatcher = currentDispatcher.current;
702
- let readHookLog;
703
727
currentDispatcher.current = DispatcherProxy;
728
+
729
+ let readHookLog;
704
730
let ancestorStackError;
731
+
705
732
try {
706
733
ancestorStackError = new Error ( ) ;
707
734
renderFunction ( props ) ;
@@ -798,19 +825,25 @@ export function inspectHooksOfFiber(
798
825
'Unknown Fiber. Needs to be a function component to inspect hooks.' ,
799
826
) ;
800
827
}
828
+
801
829
// Warm up the cache so that it doesn't consume the currentHook.
802
830
getPrimitiveStackCache();
831
+
832
+ // Set up the current hook so that we can step through and read the
833
+ // current state from them.
834
+ currentHook = (fiber.memoizedState: Hook);
835
+ currentFiber = fiber;
836
+
803
837
const type = fiber.type;
804
838
let props = fiber.memoizedProps;
805
839
if (type !== fiber.elementType) {
806
840
props = resolveDefaultProps ( type , props ) ;
807
841
}
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> ( ) ;
812
844
try {
813
845
setupContexts ( contextMap , fiber ) ;
846
+
814
847
if ( fiber . tag === ForwardRef ) {
815
848
return inspectHooksOfForwardRef (
816
849
type . render ,
@@ -820,9 +853,12 @@ export function inspectHooksOfFiber(
820
853
includeHooksSource ,
821
854
) ;
822
855
}
856
+
823
857
return inspectHooks(type, props, currentDispatcher, includeHooksSource);
824
858
} finally {
859
+ currentFiber = null ;
825
860
currentHook = null ;
861
+
826
862
restoreContexts ( contextMap ) ;
827
863
}
828
864
}
0 commit comments