diff --git a/packages/react-devtools-shared/src/__tests__/store-test.js b/packages/react-devtools-shared/src/__tests__/store-test.js
index 417158ce3a4d2..658227841aad4 100644
--- a/packages/react-devtools-shared/src/__tests__/store-test.js
+++ b/packages/react-devtools-shared/src/__tests__/store-test.js
@@ -1575,7 +1575,6 @@ describe('Store', () => {
-
@@ -1603,7 +1602,6 @@ describe('Store', () => {
[withFoo][withBar]
[Memo][withFoo][withBar]
[ForwardRef][withFoo][withBar]
-
`);
diff --git a/packages/react-devtools-shell/src/app/ElementTypes/index.js b/packages/react-devtools-shell/src/app/ElementTypes/index.js
index 4450c5682d167..b53bb9d2d119a 100644
--- a/packages/react-devtools-shell/src/app/ElementTypes/index.js
+++ b/packages/react-devtools-shell/src/app/ElementTypes/index.js
@@ -18,7 +18,6 @@ import {
Profiler,
StrictMode,
Suspense,
- unstable_Cache as Cache,
} from 'react';
const Context = createContext('abc');
diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js
index ce909b802530a..5b8dc06fb5f69 100644
--- a/packages/react-reconciler/src/ReactFiber.js
+++ b/packages/react-reconciler/src/ReactFiber.js
@@ -28,7 +28,6 @@ import {
isHostSingletonType,
} from './ReactFiberConfig';
import {
- enableCache,
enableProfilerTimer,
enableScopeAPI,
enableLegacyHidden,
@@ -66,7 +65,6 @@ import {
ScopeComponent,
OffscreenComponent,
LegacyHiddenComponent,
- CacheComponent,
TracingMarkerComponent,
} from './ReactWorkTags';
import {OffscreenVisible} from './ReactFiberActivityComponent';
@@ -104,7 +102,6 @@ import {
REACT_SCOPE_TYPE,
REACT_OFFSCREEN_TYPE,
REACT_LEGACY_HIDDEN_TYPE,
- REACT_CACHE_TYPE,
REACT_TRACING_MARKER_TYPE,
} from 'shared/ReactSymbols';
import {TransitionTracingMarker} from './ReactFiberTracingMarkerComponent';
@@ -560,11 +557,6 @@ export function createFiberFromTypeAndProps(
return createFiberFromScope(type, pendingProps, mode, lanes, key);
}
// Fall through
- case REACT_CACHE_TYPE:
- if (enableCache) {
- return createFiberFromCache(pendingProps, mode, lanes, key);
- }
- // Fall through
case REACT_TRACING_MARKER_TYPE:
if (enableTransitionTracing) {
return createFiberFromTracingMarker(pendingProps, mode, lanes, key);
@@ -807,18 +799,6 @@ export function createFiberFromLegacyHidden(
return fiber;
}
-export function createFiberFromCache(
- pendingProps: any,
- mode: TypeOfMode,
- lanes: Lanes,
- key: null | string,
-): Fiber {
- const fiber = createFiber(CacheComponent, pendingProps, key, mode);
- fiber.elementType = REACT_CACHE_TYPE;
- fiber.lanes = lanes;
- return fiber;
-}
-
export function createFiberFromTracingMarker(
pendingProps: any,
mode: TypeOfMode,
diff --git a/packages/react-reconciler/src/__tests__/ReactCacheElement-test.js b/packages/react-reconciler/src/__tests__/ReactCacheElement-test.js
deleted file mode 100644
index 19d3180af650c..0000000000000
--- a/packages/react-reconciler/src/__tests__/ReactCacheElement-test.js
+++ /dev/null
@@ -1,1597 +0,0 @@
-let React;
-let ReactNoop;
-let Cache;
-let getCacheSignal;
-let getCacheForType;
-let Scheduler;
-let assertLog;
-let act;
-let Suspense;
-let Activity;
-let useCacheRefresh;
-let startTransition;
-let useState;
-
-let textCaches;
-let seededCache;
-
-describe('ReactCacheElement', () => {
- beforeEach(() => {
- jest.resetModules();
-
- React = require('react');
- ReactNoop = require('react-noop-renderer');
- Cache = React.unstable_Cache;
- Scheduler = require('scheduler');
- act = require('internal-test-utils').act;
- Suspense = React.Suspense;
- Activity = React.unstable_Activity;
- getCacheSignal = React.unstable_getCacheSignal;
- getCacheForType = React.unstable_getCacheForType;
- useCacheRefresh = React.unstable_useCacheRefresh;
- startTransition = React.startTransition;
- useState = React.useState;
-
- const InternalTestUtils = require('internal-test-utils');
- assertLog = InternalTestUtils.assertLog;
-
- textCaches = [];
- seededCache = null;
- });
-
- function createTextCache() {
- if (seededCache !== null) {
- // Trick to seed a cache before it exists.
- // TODO: Need a built-in API to seed data before the initial render (i.e.
- // not a refresh because nothing has mounted yet).
- const textCache = seededCache;
- seededCache = null;
- return textCache;
- }
-
- const data = new Map();
- const version = textCaches.length + 1;
- const textCache = {
- version,
- data,
- resolve(text) {
- const record = data.get(text);
- if (record === undefined) {
- const newRecord = {
- status: 'resolved',
- value: text,
- cleanupScheduled: false,
- };
- data.set(text, newRecord);
- } else if (record.status === 'pending') {
- record.value.resolve();
- }
- },
- reject(text, error) {
- const record = data.get(text);
- if (record === undefined) {
- const newRecord = {
- status: 'rejected',
- value: error,
- cleanupScheduled: false,
- };
- data.set(text, newRecord);
- } else if (record.status === 'pending') {
- record.value.reject();
- }
- },
- };
- textCaches.push(textCache);
- return textCache;
- }
-
- function readText(text) {
- const signal = getCacheSignal ? getCacheSignal() : null;
- const textCache = getCacheForType(createTextCache);
- const record = textCache.data.get(text);
- if (record !== undefined) {
- if (!record.cleanupScheduled) {
- // This record was seeded prior to the abort signal being available:
- // schedule a cleanup function for it.
- // TODO: Add ability to cleanup entries seeded w useCacheRefresh()
- record.cleanupScheduled = true;
- if (getCacheSignal) {
- signal.addEventListener('abort', () => {
- Scheduler.log(`Cache cleanup: ${text} [v${textCache.version}]`);
- });
- }
- }
- switch (record.status) {
- case 'pending':
- throw record.value;
- case 'rejected':
- throw record.value;
- case 'resolved':
- return textCache.version;
- }
- } else {
- Scheduler.log(`Cache miss! [${text}]`);
-
- let resolve;
- let reject;
- const thenable = new Promise((res, rej) => {
- resolve = res;
- reject = rej;
- }).then(
- value => {
- if (newRecord.status === 'pending') {
- newRecord.status = 'resolved';
- newRecord.value = value;
- }
- },
- error => {
- if (newRecord.status === 'pending') {
- newRecord.status = 'rejected';
- newRecord.value = error;
- }
- },
- );
- thenable.resolve = resolve;
- thenable.reject = reject;
-
- const newRecord = {
- status: 'pending',
- value: thenable,
- cleanupScheduled: true,
- };
- textCache.data.set(text, newRecord);
-
- if (getCacheSignal) {
- signal.addEventListener('abort', () => {
- Scheduler.log(`Cache cleanup: ${text} [v${textCache.version}]`);
- });
- }
- throw thenable;
- }
- }
-
- function Text({text}) {
- Scheduler.log(text);
- return text;
- }
-
- function AsyncText({text, showVersion}) {
- const version = readText(text);
- const fullText = showVersion ? `${text} [v${version}]` : text;
- Scheduler.log(fullText);
- return fullText;
- }
-
- function seedNextTextCache(text) {
- if (seededCache === null) {
- seededCache = createTextCache();
- }
- seededCache.resolve(text);
- }
-
- function resolveMostRecentTextCache(text) {
- if (textCaches.length === 0) {
- throw Error('Cache does not exist.');
- } else {
- // Resolve the most recently created cache. An older cache can by
- // resolved with `textCaches[index].resolve(text)`.
- textCaches[textCaches.length - 1].resolve(text);
- }
- }
-
- // @gate enableCacheElement
- test('render Cache component', async () => {
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(Hi);
- });
- expect(root).toMatchRenderedOutput('Hi');
- });
-
- // @gate enableCacheElement
- test('mount new data', async () => {
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
-
- }>
-
-
- ,
- );
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A']);
- expect(root).toMatchRenderedOutput('A');
-
- await act(() => {
- root.render('Bye');
- });
- // no cleanup: cache is still retained at the root
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('root acts as implicit cache boundary', async () => {
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
- }>
-
- ,
- );
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A']);
- expect(root).toMatchRenderedOutput('A');
-
- await act(() => {
- root.render('Bye');
- });
- // no cleanup: cache is still retained at the root
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('multiple new Cache boundaries in the same mount share the same, fresh root cache', async () => {
- function App() {
- return (
- <>
-
- }>
-
-
-
-
- }>
-
-
-
- >
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
-
- // Even though there are two new trees, they should share the same
- // data cache. So there should be only a single cache miss for A.
- assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A', 'A']);
- expect(root).toMatchRenderedOutput('AA');
-
- await act(() => {
- root.render('Bye');
- });
- // no cleanup: cache is still retained at the root
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('multiple new Cache boundaries in the same update share the same, fresh cache', async () => {
- function App({showMore}) {
- return showMore ? (
- <>
-
- }>
-
-
-
-
- }>
-
-
-
- >
- ) : (
- '(empty)'
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
- assertLog([]);
- expect(root).toMatchRenderedOutput('(empty)');
-
- await act(() => {
- root.render();
- });
- // Even though there are two new trees, they should share the same
- // data cache. So there should be only a single cache miss for A.
- assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A', 'A']);
- expect(root).toMatchRenderedOutput('AA');
-
- await act(() => {
- root.render('Bye');
- });
- // cleanup occurs for the cache shared by the inner cache boundaries (which
- // are not shared w the root because they were added in an update)
- // note that no cache is created for the root since the cache is never accessed
- assertLog(['Cache cleanup: A [v1]']);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test(
- 'nested cache boundaries share the same cache as the root during ' +
- 'the initial render',
- async () => {
- function App() {
- return (
- }>
-
-
-
-
-
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
- // Even though there is a nested boundary, it should share the same
- // data cache as the root. So there should be only a single cache miss for A.
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A', 'A']);
- expect(root).toMatchRenderedOutput('AA');
-
- await act(() => {
- root.render('Bye');
- });
- // no cleanup: cache is still retained at the root
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- },
- );
-
- // @gate enableCacheElement
- test('new content inside an existing Cache boundary should re-use already cached data', async () => {
- function App({showMore}) {
- return (
-
- }>
-
-
- {showMore ? (
- }>
-
-
- ) : null}
-
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- seedNextTextCache('A');
- root.render();
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Add a new cache boundary
- await act(() => {
- root.render();
- });
- assertLog([
- 'A [v1]',
- // New tree should use already cached data
- 'A [v1]',
- ]);
- expect(root).toMatchRenderedOutput('A [v1]A [v1]');
-
- await act(() => {
- root.render('Bye');
- });
- // no cleanup: cache is still retained at the root
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('a new Cache boundary uses fresh cache', async () => {
- // The only difference from the previous test is that the "Show More"
- // content is wrapped in a nested boundary
- function App({showMore}) {
- return (
-
- }>
-
-
- {showMore ? (
-
- }>
-
-
-
- ) : null}
-
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- seedNextTextCache('A');
- root.render();
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Add a new cache boundary
- await act(() => {
- root.render();
- });
- assertLog([
- 'A [v1]',
- // New tree should load fresh data.
- 'Cache miss! [A]',
- 'Loading...',
- ]);
- expect(root).toMatchRenderedOutput('A [v1]Loading...');
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v2]']);
- expect(root).toMatchRenderedOutput('A [v1]A [v2]');
-
- // Replace all the children: this should retain the root Cache instance,
- // but cleanup the separate cache instance created for the fresh cache
- // boundary
- await act(() => {
- root.render('Bye!');
- });
- // Cleanup occurs for the *second* cache instance: the first is still
- // referenced by the root
- assertLog(['Cache cleanup: A [v2]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test('inner/outer cache boundaries uses the same cache instance on initial render', async () => {
- const root = ReactNoop.createRoot();
-
- function App() {
- return (
-
- }>
- {/* The shell reads A */}
-
- {/* The inner content reads both A and B */}
- }>
-
-
-
-
-
-
-
- );
- }
-
- function Shell({children}) {
- readText('A');
- return (
- <>
-
-
-
- {children}
- >
- );
- }
-
- function Content() {
- readText('A');
- readText('B');
- return ;
- }
-
- await act(() => {
- root.render();
- });
- assertLog(['Cache miss! [A]', 'Loading shell...']);
- expect(root).toMatchRenderedOutput('Loading shell...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog([
- 'Shell',
- // There's a cache miss for B, because it hasn't been read yet. But not
- // A, because it was cached when we rendered the shell.
- 'Cache miss! [B]',
- 'Loading content...',
- ]);
- expect(root).toMatchRenderedOutput(
- <>
- Shell
- Loading content...
- >,
- );
-
- await act(() => {
- resolveMostRecentTextCache('B');
- });
- assertLog(['Content']);
- expect(root).toMatchRenderedOutput(
- <>
- Shell
- Content
- >,
- );
-
- await act(() => {
- root.render('Bye');
- });
- // no cleanup: cache is still retained at the root
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('inner/ outer cache boundaries added in the same update use the same cache instance', async () => {
- const root = ReactNoop.createRoot();
-
- function App({showMore}) {
- return showMore ? (
-
- }>
- {/* The shell reads A */}
-
- {/* The inner content reads both A and B */}
- }>
-
-
-
-
-
-
-
- ) : (
- '(empty)'
- );
- }
-
- function Shell({children}) {
- readText('A');
- return (
- <>
-
-
-
- {children}
- >
- );
- }
-
- function Content() {
- readText('A');
- readText('B');
- return ;
- }
-
- await act(() => {
- root.render();
- });
- assertLog([]);
- expect(root).toMatchRenderedOutput('(empty)');
-
- await act(() => {
- root.render();
- });
- assertLog(['Cache miss! [A]', 'Loading shell...']);
- expect(root).toMatchRenderedOutput('Loading shell...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog([
- 'Shell',
- // There's a cache miss for B, because it hasn't been read yet. But not
- // A, because it was cached when we rendered the shell.
- 'Cache miss! [B]',
- 'Loading content...',
- ]);
- expect(root).toMatchRenderedOutput(
- <>
- Shell
- Loading content...
- >,
- );
-
- await act(() => {
- resolveMostRecentTextCache('B');
- });
- assertLog(['Content']);
- expect(root).toMatchRenderedOutput(
- <>
- Shell
- Content
- >,
- );
-
- await act(() => {
- root.render('Bye');
- });
- assertLog(['Cache cleanup: A [v1]', 'Cache cleanup: B [v1]']);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('refresh a cache boundary', async () => {
- let refresh;
- function App() {
- refresh = useCacheRefresh();
- return ;
- }
-
- // Mount initial data
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
- }>
-
- ,
- );
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Refresh for new data.
- await act(() => {
- startTransition(() => refresh());
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- // Note that the version has updated
- if (getCacheSignal) {
- assertLog(['A [v2]', 'Cache cleanup: A [v1]']);
- } else {
- assertLog(['A [v2]']);
- }
- expect(root).toMatchRenderedOutput('A [v2]');
-
- await act(() => {
- root.render('Bye');
- });
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('refresh the root cache', async () => {
- let refresh;
- function App() {
- refresh = useCacheRefresh();
- return ;
- }
-
- // Mount initial data
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
- }>
-
- ,
- );
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Refresh for new data.
- await act(() => {
- startTransition(() => refresh());
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- // Note that the version has updated, and the previous cache is cleared
- assertLog(['A [v2]', 'Cache cleanup: A [v1]']);
- expect(root).toMatchRenderedOutput('A [v2]');
-
- await act(() => {
- root.render('Bye');
- });
- // the original root cache already cleaned up when the refresh completed
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('refresh the root cache without a transition', async () => {
- let refresh;
- function App() {
- refresh = useCacheRefresh();
- return ;
- }
-
- // Mount initial data
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
- }>
-
- ,
- );
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Refresh for new data.
- await act(() => {
- refresh();
- });
- assertLog([
- 'Cache miss! [A]',
- 'Loading...',
- // The v1 cache can be cleaned up since everything that references it has
- // been replaced by a fallback. When the boundary switches back to visible
- // it will use the v2 cache.
- 'Cache cleanup: A [v1]',
- ]);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- // Note that the version has updated, and the previous cache is cleared
- assertLog(['A [v2]']);
- expect(root).toMatchRenderedOutput('A [v2]');
-
- await act(() => {
- root.render('Bye');
- });
- // the original root cache already cleaned up when the refresh completed
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('refresh a cache with seed data', async () => {
- let refresh;
- function App() {
- refresh = useCacheRefresh();
- return ;
- }
-
- // Mount initial data
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
-
- }>
-
-
- ,
- );
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Refresh for new data.
- await act(() => {
- // Refresh the cache with seeded data, like you would receive from a
- // server mutation.
- // TODO: Seeding multiple typed textCaches. Should work by calling `refresh`
- // multiple times with different key/value pairs
- startTransition(() => {
- const textCache = createTextCache();
- textCache.resolve('A');
- startTransition(() => refresh(createTextCache, textCache));
- });
- });
- // The root should re-render without a cache miss.
- // The cache is not cleared up yet, since it's still reference by the root
- assertLog(['A [v2]']);
- expect(root).toMatchRenderedOutput('A [v2]');
-
- await act(() => {
- root.render('Bye');
- });
- // the refreshed cache boundary is unmounted and cleans up
- assertLog(['Cache cleanup: A [v2]']);
- expect(root).toMatchRenderedOutput('Bye');
- });
-
- // @gate enableCacheElement
- test('refreshing a parent cache also refreshes its children', async () => {
- let refreshShell;
- function RefreshShell() {
- refreshShell = useCacheRefresh();
- return null;
- }
-
- function App({showMore}) {
- return (
-
-
- }>
-
-
- {showMore ? (
-
- }>
-
-
-
- ) : null}
-
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- seedNextTextCache('A');
- root.render();
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Add a new cache boundary
- await act(() => {
- seedNextTextCache('A');
- root.render();
- });
- assertLog([
- 'A [v1]',
- // New tree should load fresh data.
- 'A [v2]',
- ]);
- expect(root).toMatchRenderedOutput('A [v1]A [v2]');
-
- // Now refresh the shell. This should also cause the "Show More" contents to
- // refresh, since its cache is nested inside the outer one.
- await act(() => {
- startTransition(() => refreshShell());
- });
- assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
- expect(root).toMatchRenderedOutput('A [v1]A [v2]');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog([
- 'A [v3]',
- 'A [v3]',
- // once the refresh completes the inner showMore boundary frees its previous
- // cache instance, since it is now using the refreshed parent instance.
- 'Cache cleanup: A [v2]',
- ]);
- expect(root).toMatchRenderedOutput('A [v3]A [v3]');
-
- await act(() => {
- root.render('Bye!');
- });
- // Unmounting children releases the refreshed cache instance only; the root
- // still retains the original cache instance used for the first render
- assertLog(['Cache cleanup: A [v3]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test(
- 'refreshing a cache boundary does not refresh the other boundaries ' +
- 'that mounted at the same time (i.e. the ones that share the same cache)',
- async () => {
- let refreshFirstBoundary;
- function RefreshFirstBoundary() {
- refreshFirstBoundary = useCacheRefresh();
- return null;
- }
-
- function App({showMore}) {
- return showMore ? (
- <>
-
- }>
-
-
-
-
-
- }>
-
-
-
- >
- ) : null;
- }
-
- // First mount the initial shell without the nested boundaries. This is
- // necessary for this test because we want the two inner boundaries to be
- // treated like sibling providers that happen to share an underlying
- // cache, as opposed to consumers of the root-level cache.
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
-
- // Now reveal the boundaries. In a real app this would be a navigation.
- await act(() => {
- root.render();
- });
-
- // Even though there are two new trees, they should share the same
- // data cache. So there should be only a single cache miss for A.
- assertLog(['Cache miss! [A]', 'Loading...', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]', 'A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]A [v1]');
-
- // Refresh the first boundary. It should not refresh the second boundary,
- // even though they previously shared the same underlying cache.
- await act(async () => {
- await refreshFirstBoundary();
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v2]']);
- expect(root).toMatchRenderedOutput('A [v2]A [v1]');
-
- // Unmount children: this should clear *both* cache instances:
- // the root doesn't have a cache instance (since it wasn't accessed
- // during the initial render, and all subsequent cache accesses were within
- // a fresh boundary). Therefore this causes cleanup for both the fresh cache
- // instance in the refreshed first boundary and cleanup for the non-refreshed
- // sibling boundary.
- await act(() => {
- root.render('Bye!');
- });
- assertLog(['Cache cleanup: A [v2]', 'Cache cleanup: A [v1]']);
- expect(root).toMatchRenderedOutput('Bye!');
- },
- );
-
- // @gate enableCacheElement
- test(
- 'mount a new Cache boundary in a sibling while simultaneously ' +
- 'resolving a Suspense boundary',
- async () => {
- function App({showMore}) {
- return (
- <>
- {showMore ? (
- }>
-
-
-
-
- ) : null}
- }>
-
- {' '}
- {' '}
-
-
-
- >
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- // This will resolve the content in the first cache
- resolveMostRecentTextCache('A');
- resolveMostRecentTextCache('B');
- // And mount the second tree, which includes new content
- root.render();
- });
- assertLog([
- // The new tree should use a fresh cache
- 'Cache miss! [A]',
- 'Loading...',
- // The other tree uses the cached responses. This demonstrates that the
- // requests are not dropped.
- 'A [v1]',
- 'B [v1]',
- ]);
- expect(root).toMatchRenderedOutput('Loading... A [v1] B [v1]');
-
- // Now resolve the second tree
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v2]']);
- expect(root).toMatchRenderedOutput('A [v2] A [v1] B [v1]');
-
- await act(() => {
- root.render('Bye!');
- });
- // Unmounting children releases both cache boundaries, but the original
- // cache instance (used by second boundary) is still referenced by the root.
- // only the second cache instance is freed.
- assertLog(['Cache cleanup: A [v2]']);
- expect(root).toMatchRenderedOutput('Bye!');
- },
- );
-
- // @gate enableCacheElement
- test('cache pool is cleared once transitions that depend on it commit their shell', async () => {
- function Child({text}) {
- return (
-
-
-
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
- }>(empty),
- );
- });
- assertLog([]);
- expect(root).toMatchRenderedOutput('(empty)');
-
- await act(() => {
- startTransition(() => {
- root.render(
- }>
-
- ,
- );
- });
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('(empty)');
-
- await act(() => {
- startTransition(() => {
- root.render(
- }>
-
-
- ,
- );
- });
- });
- assertLog([
- // No cache miss, because it uses the pooled cache
- 'Loading...',
- ]);
- expect(root).toMatchRenderedOutput('(empty)');
-
- // Resolve the request
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]', 'A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]A [v1]');
-
- // Now do another transition
- await act(() => {
- startTransition(() => {
- root.render(
- }>
-
-
-
- ,
- );
- });
- });
- assertLog([
- // First two children use the old cache because they already finished
- 'A [v1]',
- 'A [v1]',
- // The new child uses a fresh cache
- 'Cache miss! [A]',
- 'Loading...',
- ]);
- expect(root).toMatchRenderedOutput('A [v1]A [v1]');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]', 'A [v1]', 'A [v2]']);
- expect(root).toMatchRenderedOutput('A [v1]A [v1]A [v2]');
-
- // Unmount children: the first text cache instance is created only after the root
- // commits, so both fresh cache instances are released by their cache boundaries,
- // cleaning up v1 (used for the first two children which render together) and
- // v2 (used for the third boundary added later).
- await act(() => {
- root.render('Bye!');
- });
- assertLog(['Cache cleanup: A [v1]', 'Cache cleanup: A [v2]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test('cache pool is not cleared by arbitrary commits', async () => {
- function App() {
- return (
- <>
-
-
- >
- );
- }
-
- let showMore;
- function ShowMore() {
- const [shouldShow, _showMore] = useState(false);
- showMore = () => _showMore(true);
- return (
- <>
- }>
- {shouldShow ? (
-
-
-
- ) : null}
-
- >
- );
- }
-
- let updateUnrelated;
- function Unrelated() {
- const [count, _updateUnrelated] = useState(0);
- updateUnrelated = _updateUnrelated;
- return ;
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
- assertLog(['0']);
- expect(root).toMatchRenderedOutput('0');
-
- await act(() => {
- startTransition(() => {
- showMore();
- });
- });
- assertLog(['Cache miss! [A]', 'Loading...']);
- expect(root).toMatchRenderedOutput('0');
-
- await act(() => {
- updateUnrelated(1);
- });
- assertLog([
- '1',
-
- // Happens to re-render the fallback. Doesn't need to, but not relevant
- // to this test.
- 'Loading...',
- ]);
- expect(root).toMatchRenderedOutput('1');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]1');
-
- // Unmount children: the first text cache instance is created only after initial
- // render after calling showMore(). This instance is cleaned up when that boundary
- // is unmounted. Bc root cache instance is never accessed, the inner cache
- // boundary ends up at v1.
- await act(() => {
- root.render('Bye!');
- });
- assertLog(['Cache cleanup: A [v1]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test('cache boundary uses a fresh cache when its key changes', async () => {
- const root = ReactNoop.createRoot();
- seedNextTextCache('A');
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- seedNextTextCache('B');
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['B [v2]']);
- expect(root).toMatchRenderedOutput('B [v2]');
-
- // Unmount children: the fresh cache instance for B cleans up since the cache boundary
- // is the only owner, while the original cache instance (for A) is still retained by
- // the root.
- await act(() => {
- root.render('Bye!');
- });
- assertLog(['Cache cleanup: B [v2]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test('overlapping transitions after an initial mount use the same fresh cache', async () => {
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['Cache miss! [A]']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // After a mount, subsequent transitions use a fresh cache
- await act(() => {
- startTransition(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- });
- assertLog(['Cache miss! [B]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Update to a different text and with a different key for the cache
- // boundary: this should still use the fresh cache instance created
- // for the earlier transition
- await act(() => {
- startTransition(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- });
- assertLog(['Cache miss! [C]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- await act(() => {
- resolveMostRecentTextCache('C');
- });
- assertLog(['C [v2]']);
- expect(root).toMatchRenderedOutput('C [v2]');
-
- // Unmount children: the fresh cache used for the updates is freed, while the
- // original cache (with A) is still retained at the root.
- await act(() => {
- root.render('Bye!');
- });
- assertLog(['Cache cleanup: B [v2]', 'Cache cleanup: C [v2]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test('overlapping updates after an initial mount use the same fresh cache', async () => {
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['Cache miss! [A]']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('A');
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // After a mount, subsequent updates use a fresh cache
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['Cache miss! [B]']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- // A second update uses the same fresh cache: even though this is a new
- // Cache boundary, the render uses the fresh cache from the pending update.
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['Cache miss! [C]']);
- expect(root).toMatchRenderedOutput('Loading...');
-
- await act(() => {
- resolveMostRecentTextCache('C');
- });
- assertLog(['C [v2]']);
- expect(root).toMatchRenderedOutput('C [v2]');
-
- // Unmount children: the fresh cache used for the updates is freed, while the
- // original cache (with A) is still retained at the root.
- await act(() => {
- root.render('Bye!');
- });
- assertLog(['Cache cleanup: B [v2]', 'Cache cleanup: C [v2]']);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test('cleans up cache only used in an aborted transition', async () => {
- const root = ReactNoop.createRoot();
- seedNextTextCache('A');
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Start a transition from A -> B..., which should create a fresh cache
- // for the new cache boundary (bc of the different key)
- await act(() => {
- startTransition(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- });
- assertLog(['Cache miss! [B]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // ...but cancel by transitioning "back" to A (which we never really left)
- await act(() => {
- startTransition(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- });
- assertLog(['A [v1]', 'Cache cleanup: B [v2]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Unmount children: ...
- await act(() => {
- root.render('Bye!');
- });
- assertLog([]);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test.skip('if a root cache refresh never commits its fresh cache is released', async () => {
- const root = ReactNoop.createRoot();
- let refresh;
- function Example({text}) {
- refresh = useCacheRefresh();
- return ;
- }
- seedNextTextCache('A');
- await act(() => {
- root.render(
-
-
- ,
- );
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- await act(() => {
- startTransition(() => {
- refresh();
- });
- });
- assertLog(['Cache miss! [A]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- await act(() => {
- root.render('Bye!');
- });
- assertLog([
- // TODO: the v1 cache should *not* be cleaned up, it is still retained by the root
- // The following line is presently yielded but should not be:
- // 'Cache cleanup: A [v1]',
-
- // TODO: the v2 cache *should* be cleaned up, it was created for the abandoned refresh
- // The following line is presently not yielded but should be:
- 'Cache cleanup: A [v2]',
- ]);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableCacheElement
- test.skip('if a cache boundary refresh never commits its fresh cache is released', async () => {
- const root = ReactNoop.createRoot();
- let refresh;
- function Example({text}) {
- refresh = useCacheRefresh();
- return ;
- }
- seedNextTextCache('A');
- await act(() => {
- root.render(
-
-
-
-
- ,
- );
- });
- assertLog(['A [v1]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- await act(() => {
- startTransition(() => {
- refresh();
- });
- });
- assertLog(['Cache miss! [A]']);
- expect(root).toMatchRenderedOutput('A [v1]');
-
- // Unmount the boundary before the refresh can complete
- await act(() => {
- root.render('Bye!');
- });
- assertLog([
- // TODO: the v2 cache *should* be cleaned up, it was created for the abandoned refresh
- // The following line is presently not yielded but should be:
- 'Cache cleanup: A [v2]',
- ]);
- expect(root).toMatchRenderedOutput('Bye!');
- });
-
- // @gate enableActivity
- // @gate enableCache
- test('prerender a new cache boundary inside an Activity tree', async () => {
- function App({prerenderMore}) {
- return (
-
-
- {prerenderMore ? (
-
-
-
- ) : null}
-
-
- );
- }
-
- const root = ReactNoop.createRoot();
- await act(() => {
- root.render();
- });
- assertLog([]);
- expect(root).toMatchRenderedOutput();
-
- seedNextTextCache('More');
- await act(() => {
- root.render();
- });
- assertLog(['More']);
- expect(root).toMatchRenderedOutput(More
);
- });
-});
diff --git a/packages/react/index.classic.fb.js b/packages/react/index.classic.fb.js
index c8a3a6012a27a..8c670383b6ecb 100644
--- a/packages/react/index.classic.fb.js
+++ b/packages/react/index.classic.fb.js
@@ -29,7 +29,6 @@ export {
cache,
startTransition,
unstable_Activity,
- unstable_Cache,
unstable_TracingMarker,
unstable_DebugTracingMode,
unstable_LegacyHidden,
diff --git a/packages/react/index.experimental.js b/packages/react/index.experimental.js
index 1adaed959e512..e62e7853c595d 100644
--- a/packages/react/index.experimental.js
+++ b/packages/react/index.experimental.js
@@ -28,7 +28,6 @@ export {
memo,
cache,
startTransition,
- unstable_Cache,
unstable_DebugTracingMode,
unstable_Activity,
unstable_postpone,
diff --git a/packages/react/index.js b/packages/react/index.js
index 2f267f6eeb0c0..e8f7b107884b9 100644
--- a/packages/react/index.js
+++ b/packages/react/index.js
@@ -49,7 +49,6 @@ export {
memo,
cache,
startTransition,
- unstable_Cache,
unstable_DebugTracingMode,
unstable_LegacyHidden,
unstable_Activity,
diff --git a/packages/react/index.modern.fb.js b/packages/react/index.modern.fb.js
index d5d9a10f4ca93..671b156214dca 100644
--- a/packages/react/index.modern.fb.js
+++ b/packages/react/index.modern.fb.js
@@ -28,7 +28,6 @@ export {
memo,
cache,
startTransition,
- unstable_Cache,
unstable_DebugTracingMode,
unstable_LegacyHidden,
unstable_Activity,
diff --git a/packages/react/src/ReactClient.js b/packages/react/src/ReactClient.js
index 83bcdcc8226a2..4f9e7cbc0a34b 100644
--- a/packages/react/src/ReactClient.js
+++ b/packages/react/src/ReactClient.js
@@ -18,7 +18,6 @@ import {
REACT_LEGACY_HIDDEN_TYPE,
REACT_OFFSCREEN_TYPE,
REACT_SCOPE_TYPE,
- REACT_CACHE_TYPE,
REACT_TRACING_MARKER_TYPE,
} from 'shared/ReactSymbols';
@@ -119,7 +118,6 @@ export {
getCacheSignal as unstable_getCacheSignal,
getCacheForType as unstable_getCacheForType,
useCacheRefresh as unstable_useCacheRefresh,
- REACT_CACHE_TYPE as unstable_Cache,
use,
useMemoCache as unstable_useMemoCache,
// enableScopeAPI
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index 4d4fc361f4879..7113757b66676 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -75,7 +75,6 @@ export const enableLegacyFBSupport = false;
export const enableCache = true;
export const enableLegacyCache = __EXPERIMENTAL__;
-export const enableCacheElement = __EXPERIMENTAL__;
export const enableFetchInstrumentation = true;
export const enableBinaryFlight = __EXPERIMENTAL__;
diff --git a/packages/shared/ReactSymbols.js b/packages/shared/ReactSymbols.js
index 6dca3476be945..32f3ef654068d 100644
--- a/packages/shared/ReactSymbols.js
+++ b/packages/shared/ReactSymbols.js
@@ -35,7 +35,6 @@ export const REACT_OFFSCREEN_TYPE: symbol = Symbol.for('react.offscreen');
export const REACT_LEGACY_HIDDEN_TYPE: symbol = Symbol.for(
'react.legacy_hidden',
);
-export const REACT_CACHE_TYPE: symbol = Symbol.for('react.cache');
export const REACT_TRACING_MARKER_TYPE: symbol = Symbol.for(
'react.tracing_marker',
);
diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js
index 13e8d00c5b3b3..1a5636531feb6 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -43,7 +43,6 @@ export const enableProfilerNestedUpdatePhase = __PROFILE__;
export const enableUpdaterTracking = __PROFILE__;
export const enableCache = true;
export const enableLegacyCache = false;
-export const enableCacheElement = true;
export const enableFetchInstrumentation = false;
export const enableBinaryFlight = true;
export const enableTaint = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index 904f165c214cb..4287a6afba3e3 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -48,7 +48,6 @@ export const enableRenderableContext = __TODO_NEXT_RN_MAJOR__;
const __NEXT_RN_MAJOR__ = true;
export const disableClientCache = __NEXT_RN_MAJOR__;
export const disableLegacyContext = __NEXT_RN_MAJOR__;
-export const enableCacheElement = __NEXT_RN_MAJOR__;
export const enableTaint = __NEXT_RN_MAJOR__;
export const enableUnifiedSyncLane = __NEXT_RN_MAJOR__;
export const enableFizzExternalRuntime = __NEXT_RN_MAJOR__; // DOM-only
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index df84dd4d4cc60..67ef3589ca487 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -20,7 +20,6 @@ export const enableProfilerNestedUpdatePhase = __PROFILE__;
export const enableUpdaterTracking = false;
export const enableCache = true;
export const enableLegacyCache = __EXPERIMENTAL__;
-export const enableCacheElement = __EXPERIMENTAL__;
export const enableFetchInstrumentation = true;
export const enableBinaryFlight = true;
export const enableTaint = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
index 879806d751575..4a860268d035e 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
@@ -20,7 +20,6 @@ export const enableProfilerNestedUpdatePhase = __PROFILE__;
export const enableUpdaterTracking = false;
export const enableCache = true;
export const enableLegacyCache = false;
-export const enableCacheElement = true;
export const enableFetchInstrumentation = false;
export const enableBinaryFlight = true;
export const enableTaint = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index 137852fad7c5c..9f95dacd7ab61 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -20,7 +20,6 @@ export const enableProfilerNestedUpdatePhase = __PROFILE__;
export const enableUpdaterTracking = false;
export const enableCache = true;
export const enableLegacyCache = true;
-export const enableCacheElement = true;
export const enableFetchInstrumentation = false;
export const enableBinaryFlight = true;
export const enableTaint = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 79ff994a0ad2d..1892d6f2020fa 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -68,7 +68,6 @@ export const enableGetInspectorDataForInstanceInProduction = false;
export const enableCache = true;
export const enableLegacyCache = true;
-export const enableCacheElement = true;
export const enableFetchInstrumentation = false;
export const enableBinaryFlight = false;
diff --git a/packages/shared/getComponentNameFromType.js b/packages/shared/getComponentNameFromType.js
index fb63ff465a6af..b0e2a0f782a53 100644
--- a/packages/shared/getComponentNameFromType.js
+++ b/packages/shared/getComponentNameFromType.js
@@ -23,13 +23,11 @@ import {
REACT_SUSPENSE_TYPE,
REACT_SUSPENSE_LIST_TYPE,
REACT_LAZY_TYPE,
- REACT_CACHE_TYPE,
REACT_TRACING_MARKER_TYPE,
} from 'shared/ReactSymbols';
import {
enableTransitionTracing,
- enableCache,
enableRenderableContext,
} from './ReactFeatureFlags';
@@ -83,10 +81,6 @@ export default function getComponentNameFromType(type: mixed): string | null {
return 'Suspense';
case REACT_SUSPENSE_LIST_TYPE:
return 'SuspenseList';
- case REACT_CACHE_TYPE:
- if (enableCache) {
- return 'Cache';
- }
// Fall through
case REACT_TRACING_MARKER_TYPE:
if (enableTransitionTracing) {
diff --git a/packages/shared/isValidElementType.js b/packages/shared/isValidElementType.js
index aa2092a923dfc..6f0edaf8ea241 100644
--- a/packages/shared/isValidElementType.js
+++ b/packages/shared/isValidElementType.js
@@ -23,12 +23,10 @@ import {
REACT_SCOPE_TYPE,
REACT_LEGACY_HIDDEN_TYPE,
REACT_OFFSCREEN_TYPE,
- REACT_CACHE_TYPE,
REACT_TRACING_MARKER_TYPE,
} from 'shared/ReactSymbols';
import {
enableScopeAPI,
- enableCacheElement,
enableTransitionTracing,
enableDebugTracing,
enableLegacyHidden,
@@ -53,7 +51,6 @@ export default function isValidElementType(type: mixed): boolean {
(enableLegacyHidden && type === REACT_LEGACY_HIDDEN_TYPE) ||
type === REACT_OFFSCREEN_TYPE ||
(enableScopeAPI && type === REACT_SCOPE_TYPE) ||
- (enableCacheElement && type === REACT_CACHE_TYPE) ||
(enableTransitionTracing && type === REACT_TRACING_MARKER_TYPE)
) {
return true;