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:
Joseph Savona 2022-10-14 15:00:31 -07:00 committed by GitHub
parent 3b814327e2
commit 69c7246d9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 41 additions and 8 deletions

View File

@ -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__) {

View File

@ -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__) {

View File

@ -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();

View File

@ -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 {}

View File

@ -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),
};

View File

@ -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';