mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
fix[devtools/useMemoCache]: add stub for useMemoCache in ReactDebugHook (#27472)
Currently, we have this error in our logs of the internal version of
React DevTools:
```
TypeError: Cannot read properties of undefined (reading 'memoCache')
at Proxy.useMemoCache (chrome-extension://dnjnjgbfilfphmojnmhliehogmojhclc/build/react_devtools_backend_compact.js:151:71)
```
Looking at the build files of the extension, it fails here:
https://github.com/facebook/react/blob/dddfe688206dafa5646550d351eb9a8e9c53654a/packages/react-debug-tools/src/ReactDebugHooks.js#L333-L337
Looks like `updateQueue` can be `undefined`, as it is not defined in
hook object here:
https://github.com/facebook/react/blob/dddfe688206dafa5646550d351eb9a8e9c53654a/packages/react-reconciler/src/ReactFiberHooks.js#L180-L186
~~Also, it looks like `useMemoCache` implementation doesn't expect this,
so it should also result into TypeError here, line 1114:~~
https://github.com/facebook/react/blob/dddfe688206dafa5646550d351eb9a8e9c53654a/packages/react-reconciler/src/ReactFiberHooks.js#L1108-L1115
~~Should this also be updated?~~
This commit is contained in:
+6
-41
@@ -48,19 +48,9 @@ type Dispatch<A> = A => void;
|
||||
|
||||
let primitiveStackCache: null | Map<string, Array<any>> = null;
|
||||
|
||||
type MemoCache = {
|
||||
data: Array<Array<any>>,
|
||||
index: number,
|
||||
};
|
||||
|
||||
type FunctionComponentUpdateQueue = {
|
||||
memoCache?: MemoCache | null,
|
||||
};
|
||||
|
||||
type Hook = {
|
||||
memoizedState: any,
|
||||
next: Hook | null,
|
||||
updateQueue: FunctionComponentUpdateQueue | null,
|
||||
};
|
||||
|
||||
function getPrimitiveStackCache(): Map<string, Array<any>> {
|
||||
@@ -327,36 +317,11 @@ function useId(): string {
|
||||
return id;
|
||||
}
|
||||
|
||||
// useMemoCache is an implementation detail of Forget's memoization
|
||||
// it should not be called directly in user-generated code
|
||||
// we keep it as a stub for dispatcher
|
||||
function useMemoCache(size: number): Array<any> {
|
||||
const hook = nextHook();
|
||||
let memoCache: MemoCache;
|
||||
if (
|
||||
hook !== null &&
|
||||
hook.updateQueue !== null &&
|
||||
hook.updateQueue.memoCache != null
|
||||
) {
|
||||
memoCache = hook.updateQueue.memoCache;
|
||||
} else {
|
||||
memoCache = {
|
||||
data: [],
|
||||
index: 0,
|
||||
};
|
||||
}
|
||||
|
||||
let data = memoCache.data[memoCache.index];
|
||||
if (data === undefined) {
|
||||
const MEMO_CACHE_SENTINEL = Symbol.for('react.memo_cache_sentinel');
|
||||
data = new Array(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
data[i] = MEMO_CACHE_SENTINEL;
|
||||
}
|
||||
}
|
||||
hookLog.push({
|
||||
primitive: 'MemoCache',
|
||||
stackError: new Error(),
|
||||
value: data,
|
||||
});
|
||||
return data;
|
||||
return [];
|
||||
}
|
||||
|
||||
const Dispatcher: DispatcherType = {
|
||||
@@ -725,7 +690,7 @@ export function inspectHooks<Props>(
|
||||
renderFunction: Props => React$Node,
|
||||
props: Props,
|
||||
currentDispatcher: ?CurrentDispatcherRef,
|
||||
includeHooksSource?: boolean = false,
|
||||
includeHooksSource: boolean = false,
|
||||
): HooksTree {
|
||||
// DevTools will pass the current renderer's injected dispatcher.
|
||||
// Other apps might compile debug hooks as part of their app though.
|
||||
@@ -816,7 +781,7 @@ function resolveDefaultProps(Component: any, baseProps: any) {
|
||||
export function inspectHooksOfFiber(
|
||||
fiber: Fiber,
|
||||
currentDispatcher: ?CurrentDispatcherRef,
|
||||
includeHooksSource?: boolean = false,
|
||||
includeHooksSource: boolean = false,
|
||||
): HooksTree {
|
||||
// DevTools will pass the current renderer's injected dispatcher.
|
||||
// Other apps might compile debug hooks as part of their app though.
|
||||
|
||||
+2
-6
@@ -634,7 +634,7 @@ describe('ReactHooksInspectionIntegration', () => {
|
||||
});
|
||||
|
||||
// @gate enableUseMemoCacheHook
|
||||
it('should support useMemoCache hook', () => {
|
||||
it('useMemoCache should not be inspectable', () => {
|
||||
function Foo() {
|
||||
const $ = useMemoCache(1);
|
||||
let t0;
|
||||
@@ -653,11 +653,7 @@ describe('ReactHooksInspectionIntegration', () => {
|
||||
const childFiber = renderer.root.findByType(Foo)._currentFiber();
|
||||
const tree = ReactDebugTools.inspectHooksOfFiber(childFiber);
|
||||
|
||||
expect(tree.length).toEqual(1);
|
||||
expect(tree[0].isStateEditable).toBe(false);
|
||||
expect(tree[0].name).toBe('MemoCache');
|
||||
expect(tree[0].value).toHaveLength(1);
|
||||
expect(tree[0].value[0]).toEqual(<div>{1}</div>);
|
||||
expect(tree.length).toEqual(0);
|
||||
});
|
||||
|
||||
describe('useDebugValue', () => {
|
||||
|
||||
+2
@@ -18,6 +18,7 @@ import EdgeCaseObjects from './EdgeCaseObjects.js';
|
||||
import NestedProps from './NestedProps';
|
||||
import SimpleValues from './SimpleValues';
|
||||
import SymbolKeys from './SymbolKeys';
|
||||
import UseMemoCache from './UseMemoCache';
|
||||
|
||||
// TODO Add Immutable JS example
|
||||
|
||||
@@ -34,6 +35,7 @@ export default function InspectableElements(): React.Node {
|
||||
<EdgeCaseObjects />
|
||||
<CircularReferences />
|
||||
<SymbolKeys />
|
||||
<UseMemoCache />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export default function UseMemoCache(): React.Node {
|
||||
React.unstable_useMemoCache(1);
|
||||
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user