Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize useMemoCache with sentinel values #25465

Merged
merged 4 commits into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions packages/react-reconciler/src/ReactFiberHooks.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
import {
REACT_CONTEXT_TYPE,
REACT_SERVER_CONTEXT_TYPE,
REACT_MEMO_CACHE_SENTINEL,
} from 'shared/ReactSymbols';

import {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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__) {
Expand Down
6 changes: 4 additions & 2 deletions packages/react-reconciler/src/ReactFiberHooks.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import {
import {
REACT_CONTEXT_TYPE,
REACT_SERVER_CONTEXT_TYPE,
REACT_MEMO_CACHE_SENTINEL,
} from 'shared/ReactSymbols';

import {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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__) {
Expand Down
15 changes: 14 additions & 1 deletion packages/react-reconciler/src/__tests__/useMemoCache-test.js
Original file line number Diff line number Diff line change
@@ -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()', () => {
Expand All @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down
7 changes: 6 additions & 1 deletion packages/react-server/src/ReactFizzHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {}
Expand Down
11 changes: 9 additions & 2 deletions packages/react-server/src/ReactFlightHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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),
};
Expand Down
4 changes: 4 additions & 0 deletions packages/shared/ReactSymbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down