Skip to content

Commit 69c7246

Browse files
authored
Initialize useMemoCache with sentinel values (#25465)
* Flush out useMemoCache API * rename symbol * rename symbol.for string name * workaround symbol export not working in unit tests
1 parent 3b81432 commit 69c7246

File tree

6 files changed

+41
-8
lines changed

6 files changed

+41
-8
lines changed

packages/react-reconciler/src/ReactFiberHooks.new.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
import {
4747
REACT_CONTEXT_TYPE,
4848
REACT_SERVER_CONTEXT_TYPE,
49+
REACT_MEMO_CACHE_SENTINEL,
4950
} from 'shared/ReactSymbols';
5051

5152
import {
@@ -845,8 +846,6 @@ function useMemoCache(size: number): Array<any> {
845846
memoCache = updateQueue.memoCache;
846847
}
847848
// Otherwise clone from the current fiber
848-
// TODO: not sure how to access the current fiber here other than going through
849-
// currentlyRenderingFiber.alternate
850849
if (memoCache == null) {
851850
const current: Fiber | null = currentlyRenderingFiber.alternate;
852851
if (current !== null) {
@@ -878,6 +877,9 @@ function useMemoCache(size: number): Array<any> {
878877
let data = memoCache.data[memoCache.index];
879878
if (data === undefined) {
880879
data = memoCache.data[memoCache.index] = new Array(size);
880+
for (let i = 0; i < size; i++) {
881+
data[i] = REACT_MEMO_CACHE_SENTINEL;
882+
}
881883
} else if (data.length !== size) {
882884
// TODO: consider warning or throwing here
883885
if (__DEV__) {

packages/react-reconciler/src/ReactFiberHooks.old.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import {
4646
import {
4747
REACT_CONTEXT_TYPE,
4848
REACT_SERVER_CONTEXT_TYPE,
49+
REACT_MEMO_CACHE_SENTINEL,
4950
} from 'shared/ReactSymbols';
5051

5152
import {
@@ -845,8 +846,6 @@ function useMemoCache(size: number): Array<any> {
845846
memoCache = updateQueue.memoCache;
846847
}
847848
// Otherwise clone from the current fiber
848-
// TODO: not sure how to access the current fiber here other than going through
849-
// currentlyRenderingFiber.alternate
850849
if (memoCache == null) {
851850
const current: Fiber | null = currentlyRenderingFiber.alternate;
852851
if (current !== null) {
@@ -878,6 +877,9 @@ function useMemoCache(size: number): Array<any> {
878877
let data = memoCache.data[memoCache.index];
879878
if (data === undefined) {
880879
data = memoCache.data[memoCache.index] = new Array(size);
880+
for (let i = 0; i < size; i++) {
881+
data[i] = REACT_MEMO_CACHE_SENTINEL;
882+
}
881883
} else if (data.length !== size) {
882884
// TODO: consider warning or throwing here
883885
if (__DEV__) {

packages/react-reconciler/src/__tests__/useMemoCache-test.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @emails react-core
8+
* @jest-environment node
9+
*/
10+
111
let React;
212
let ReactNoop;
313
let act;
414
let useState;
515
let useMemoCache;
16+
let MemoCacheSentinel;
617
let ErrorBoundary;
718

819
describe('useMemoCache()', () => {
@@ -14,6 +25,7 @@ describe('useMemoCache()', () => {
1425
act = require('jest-react').act;
1526
useState = React.useState;
1627
useMemoCache = React.unstable_useMemoCache;
28+
MemoCacheSentinel = Symbol.for('react.memo_cache_sentinel');
1729

1830
class _ErrorBoundary extends React.Component {
1931
constructor(props) {
@@ -46,7 +58,8 @@ describe('useMemoCache()', () => {
4658
const cache = useMemoCache(1);
4759
expect(Array.isArray(cache)).toBe(true);
4860
expect(cache.length).toBe(1);
49-
expect(cache[0]).toBe(undefined);
61+
expect(cache[0]).toBe(MemoCacheSentinel);
62+
5063
return 'Ok';
5164
}
5265
const root = ReactNoop.createRoot();

packages/react-server/src/ReactFizzHooks.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import is from 'shared/objectIs';
4646
import {
4747
REACT_SERVER_CONTEXT_TYPE,
4848
REACT_CONTEXT_TYPE,
49+
REACT_MEMO_CACHE_SENTINEL,
4950
} from 'shared/ReactSymbols';
5051

5152
type BasicStateAction<S> = (S => S) | S;
@@ -666,7 +667,11 @@ function useCacheRefresh(): <T>(?() => T, ?T) => void {
666667
}
667668

668669
function useMemoCache(size: number): Array<any> {
669-
return new Array(size);
670+
const data = new Array(size);
671+
for (let i = 0; i < size; i++) {
672+
data[i] = REACT_MEMO_CACHE_SENTINEL;
673+
}
674+
return data;
670675
}
671676

672677
function noop(): void {}

packages/react-server/src/ReactFlightHooks.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import type {Dispatcher} from 'react-reconciler/src/ReactInternalTypes';
1111
import type {Request} from './ReactFlightServer';
1212
import type {ReactServerContext, Thenable, Usable} from 'shared/ReactTypes';
1313
import type {ThenableState} from './ReactFlightWakeable';
14-
import {REACT_SERVER_CONTEXT_TYPE} from 'shared/ReactSymbols';
14+
import {
15+
REACT_SERVER_CONTEXT_TYPE,
16+
REACT_MEMO_CACHE_SENTINEL,
17+
} from 'shared/ReactSymbols';
1518
import {readContext as readContextImpl} from './ReactFlightNewContext';
1619
import {enableUseHook} from 'shared/ReactFeatureFlags';
1720
import {
@@ -90,7 +93,11 @@ export const HooksDispatcher: Dispatcher = {
9093
return unsupportedRefresh;
9194
},
9295
useMemoCache(size: number): Array<any> {
93-
return new Array(size);
96+
const data = new Array(size);
97+
for (let i = 0; i < size; i++) {
98+
data[i] = REACT_MEMO_CACHE_SENTINEL;
99+
}
100+
return data;
94101
},
95102
use: enableUseHook ? use : (unsupportedHook: any),
96103
};

packages/shared/ReactSymbols.js

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ export const REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED: symbol = Symbol.for(
4545
'react.default_value',
4646
);
4747

48+
export const REACT_MEMO_CACHE_SENTINEL: symbol = Symbol.for(
49+
'react.memo_cache_sentinel',
50+
);
51+
4852
const MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
4953
const FAUX_ITERATOR_SYMBOL = '@@iterator';
5054

0 commit comments

Comments
 (0)