Skip to content

Commit 6b66aed

Browse files
committed
Remove client caching from cache API
We haven't yet decided how we want `cache` to work on the client. The lifetime of the cache is more complex than on the server, where it only has to live as long as a single request. Since it's more important to ship this on the server, we're removing the existing behavior from the client for now. On the client (i.e. not a Server Components environment) `cache` will have not have any caching behavior. The rest of the behavior is the same as the server implementation — it returns a new reference, extra properties like `displayName` are not preserved, the length of the new function is 0, etc. That way apps can't accidentally depend on those details. We intend to implement client caching in a future major release. In the meantime, it's only exposed as an API so that Shared Components can use per-request caching on the server without breaking on the client.
1 parent b8f14f9 commit 6b66aed

File tree

6 files changed

+51
-3
lines changed

6 files changed

+51
-3
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,25 @@ describe('ReactCache', () => {
199199
expect(x).toBe(y);
200200
expect(z).not.toBe(x);
201201
});
202+
203+
// @gate enableCache
204+
it('introspection of returned wrapper function is same on client and server', async () => {
205+
// When the variant flag is true, test the client version of `cache`.
206+
if (gate(flags => flags.variant)) {
207+
jest.resetModules();
208+
jest.mock('react', () => jest.requireActual('react'));
209+
const ClientReact = require('react');
210+
cache = ClientReact.cache;
211+
}
212+
213+
function foo(a, b, c) {
214+
return a + b + c;
215+
}
216+
foo.displayName = 'Custom display name';
217+
218+
const cachedFoo = cache(foo);
219+
expect(cachedFoo).not.toBe(foo);
220+
expect(cachedFoo.length).toBe(0);
221+
expect(cachedFoo.displayName).toBe(undefined);
222+
});
202223
});
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright (c) Meta Platforms, 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+
* @flow
8+
*/
9+
10+
export function cache<A: Iterable<mixed>, T>(fn: (...A) => T): (...A) => T {
11+
// On the client (i.e. not a Server Components environment) `cache` has
12+
// no caching behavior. We just return the function as-is.
13+
//
14+
// We intend to implement client caching in a future major release. In the
15+
// meantime, it's only exposed as an API so that Shared Components can use
16+
// per-request caching on the server without breaking on the client. But it
17+
// does mean they need to be aware of the behavioral difference.
18+
//
19+
// The rest of the behavior is the same as the server implementation — it
20+
// returns a new reference, extra properties like `displayName` are not
21+
// preserved, the length of the new function is 0, etc. That way apps can't
22+
// accidentally depend on those details.
23+
return function () {
24+
// $FlowFixMe[incompatible-call]: We don't want to use rest arguments since we transpile the code.
25+
return fn.apply(null, arguments);
26+
};
27+
}

packages/react/src/ReactClient.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {createContext} from './ReactContext';
3535
import {lazy} from './ReactLazy';
3636
import {forwardRef} from './ReactForwardRef';
3737
import {memo} from './ReactMemo';
38-
import {cache} from './ReactCache';
38+
import {cache} from './ReactCacheClient';
3939
import {postpone} from './ReactPostpone';
4040
import {
4141
getCacheSignal,

packages/react/src/ReactServer.experimental.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
import {forwardRef} from './ReactForwardRef';
3939
import {lazy} from './ReactLazy';
4040
import {memo} from './ReactMemo';
41-
import {cache} from './ReactCache';
41+
import {cache} from './ReactCacheServer';
4242
import {startTransition} from './ReactStartTransition';
4343
import {postpone} from './ReactPostpone';
4444
import version from 'shared/ReactVersion';

packages/react/src/ReactServer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {
3535
import {forwardRef} from './ReactForwardRef';
3636
import {lazy} from './ReactLazy';
3737
import {memo} from './ReactMemo';
38-
import {cache} from './ReactCache';
38+
import {cache} from './ReactCacheServer';
3939
import {startTransition} from './ReactStartTransition';
4040
import version from 'shared/ReactVersion';
4141

0 commit comments

Comments
 (0)