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
This commit is contained in:
parent
3b814327e2
commit
69c7246d9d
|
@ -46,6 +46,7 @@ import {
|
|||
import {
|
||||
REACT_CONTEXT_TYPE,
|
||||
REACT_SERVER_CONTEXT_TYPE,
|
||||
REACT_MEMO_CACHE_SENTINEL,
|
||||
} from 'shared/ReactSymbols';
|
||||
|
||||
import {
|
||||
|
@ -845,8 +846,6 @@ function useMemoCache(size: number): Array<any> {
|
|||
memoCache = updateQueue.memoCache;
|
||||
}
|
||||
// Otherwise clone from the current fiber
|
||||
// TODO: not sure how to access the current fiber here other than going through
|
||||
// currentlyRenderingFiber.alternate
|
||||
if (memoCache == null) {
|
||||
const current: Fiber | null = currentlyRenderingFiber.alternate;
|
||||
if (current !== null) {
|
||||
|
@ -878,6 +877,9 @@ function useMemoCache(size: number): Array<any> {
|
|||
let data = memoCache.data[memoCache.index];
|
||||
if (data === undefined) {
|
||||
data = memoCache.data[memoCache.index] = new Array(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
data[i] = REACT_MEMO_CACHE_SENTINEL;
|
||||
}
|
||||
} else if (data.length !== size) {
|
||||
// TODO: consider warning or throwing here
|
||||
if (__DEV__) {
|
||||
|
|
|
@ -46,6 +46,7 @@ import {
|
|||
import {
|
||||
REACT_CONTEXT_TYPE,
|
||||
REACT_SERVER_CONTEXT_TYPE,
|
||||
REACT_MEMO_CACHE_SENTINEL,
|
||||
} from 'shared/ReactSymbols';
|
||||
|
||||
import {
|
||||
|
@ -845,8 +846,6 @@ function useMemoCache(size: number): Array<any> {
|
|||
memoCache = updateQueue.memoCache;
|
||||
}
|
||||
// Otherwise clone from the current fiber
|
||||
// TODO: not sure how to access the current fiber here other than going through
|
||||
// currentlyRenderingFiber.alternate
|
||||
if (memoCache == null) {
|
||||
const current: Fiber | null = currentlyRenderingFiber.alternate;
|
||||
if (current !== null) {
|
||||
|
@ -878,6 +877,9 @@ function useMemoCache(size: number): Array<any> {
|
|||
let data = memoCache.data[memoCache.index];
|
||||
if (data === undefined) {
|
||||
data = memoCache.data[memoCache.index] = new Array(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
data[i] = REACT_MEMO_CACHE_SENTINEL;
|
||||
}
|
||||
} else if (data.length !== size) {
|
||||
// TODO: consider warning or throwing here
|
||||
if (__DEV__) {
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
* @jest-environment node
|
||||
*/
|
||||
|
||||
let React;
|
||||
let ReactNoop;
|
||||
let act;
|
||||
let useState;
|
||||
let useMemoCache;
|
||||
let MemoCacheSentinel;
|
||||
let ErrorBoundary;
|
||||
|
||||
describe('useMemoCache()', () => {
|
||||
|
@ -14,6 +25,7 @@ describe('useMemoCache()', () => {
|
|||
act = require('jest-react').act;
|
||||
useState = React.useState;
|
||||
useMemoCache = React.unstable_useMemoCache;
|
||||
MemoCacheSentinel = Symbol.for('react.memo_cache_sentinel');
|
||||
|
||||
class _ErrorBoundary extends React.Component {
|
||||
constructor(props) {
|
||||
|
@ -46,7 +58,8 @@ describe('useMemoCache()', () => {
|
|||
const cache = useMemoCache(1);
|
||||
expect(Array.isArray(cache)).toBe(true);
|
||||
expect(cache.length).toBe(1);
|
||||
expect(cache[0]).toBe(undefined);
|
||||
expect(cache[0]).toBe(MemoCacheSentinel);
|
||||
|
||||
return 'Ok';
|
||||
}
|
||||
const root = ReactNoop.createRoot();
|
||||
|
|
|
@ -46,6 +46,7 @@ import is from 'shared/objectIs';
|
|||
import {
|
||||
REACT_SERVER_CONTEXT_TYPE,
|
||||
REACT_CONTEXT_TYPE,
|
||||
REACT_MEMO_CACHE_SENTINEL,
|
||||
} from 'shared/ReactSymbols';
|
||||
|
||||
type BasicStateAction<S> = (S => S) | S;
|
||||
|
@ -666,7 +667,11 @@ function useCacheRefresh(): <T>(?() => T, ?T) => void {
|
|||
}
|
||||
|
||||
function useMemoCache(size: number): Array<any> {
|
||||
return new Array(size);
|
||||
const data = new Array(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
data[i] = REACT_MEMO_CACHE_SENTINEL;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
function noop(): void {}
|
||||
|
|
|
@ -11,7 +11,10 @@ import type {Dispatcher} from 'react-reconciler/src/ReactInternalTypes';
|
|||
import type {Request} from './ReactFlightServer';
|
||||
import type {ReactServerContext, Thenable, Usable} from 'shared/ReactTypes';
|
||||
import type {ThenableState} from './ReactFlightWakeable';
|
||||
import {REACT_SERVER_CONTEXT_TYPE} from 'shared/ReactSymbols';
|
||||
import {
|
||||
REACT_SERVER_CONTEXT_TYPE,
|
||||
REACT_MEMO_CACHE_SENTINEL,
|
||||
} from 'shared/ReactSymbols';
|
||||
import {readContext as readContextImpl} from './ReactFlightNewContext';
|
||||
import {enableUseHook} from 'shared/ReactFeatureFlags';
|
||||
import {
|
||||
|
@ -90,7 +93,11 @@ export const HooksDispatcher: Dispatcher = {
|
|||
return unsupportedRefresh;
|
||||
},
|
||||
useMemoCache(size: number): Array<any> {
|
||||
return new Array(size);
|
||||
const data = new Array(size);
|
||||
for (let i = 0; i < size; i++) {
|
||||
data[i] = REACT_MEMO_CACHE_SENTINEL;
|
||||
}
|
||||
return data;
|
||||
},
|
||||
use: enableUseHook ? use : (unsupportedHook: any),
|
||||
};
|
||||
|
|
|
@ -45,6 +45,10 @@ export const REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED: symbol = Symbol.for(
|
|||
'react.default_value',
|
||||
);
|
||||
|
||||
export const REACT_MEMO_CACHE_SENTINEL: symbol = Symbol.for(
|
||||
'react.memo_cache_sentinel',
|
||||
);
|
||||
|
||||
const MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
|
||||
const FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
|
||||
|
|
Loading…
Reference in New Issue