Bug fix when resolving cache (#25545)
We must use the asynclocalstorage one if it's available.
Sebastian Markbåge committed
Oct 23, 2022 at 14:12 UTC
1d3fc9c9c4d88536dcc36a0c771c6bb75f68f78b
2 files changed
+29
-4
packages/react-server/src/ReactFlightCache.js
+6
-4
@@ -32,21 +32,23 @@ function resolveCache(): Map<Function, mixed> {
32
33
export const DefaultCacheDispatcher: CacheDispatcher = {
34
getCacheSignal(): AbortSignal {
35
- let entry: AbortSignal | void = (resolveCache().get(createSignal): any);
35
+ const cache = resolveCache();
36
+ let entry: AbortSignal | void = (cache.get(createSignal): any);
37
if (entry === undefined) {
38
entry = createSignal();
39
// $FlowFixMe[incompatible-use] found when upgrading Flow
39
- currentCache.set(createSignal, entry);
40
+ cache.set(createSignal, entry);
41
}
42
return entry;
43
},
44
getCacheForType<T>(resourceType: () => T): T {
44
- let entry: T | void = (resolveCache().get(resourceType): any);
45
+ const cache = resolveCache();
46
+ let entry: T | void = (cache.get(resourceType): any);
47
if (entry === undefined) {
48
entry = resourceType();
49
// TODO: Warn if undefined?
50
// $FlowFixMe[incompatible-use] found when upgrading Flow
49
- currentCache.set(resourceType, entry);
51
+ cache.set(resourceType, entry);
52
}
53
return entry;
54
},
packages/react/src/__tests__/ReactFetch-test.js
+23
@@ -36,6 +36,7 @@ let React;
36
let ReactServerDOMServer;
37
let ReactServerDOMClient;
38
let use;
39
+let cache;
40
41
describe('ReactFetch', () => {
42
beforeEach(() => {
@@ -50,6 +51,7 @@ describe('ReactFetch', () => {
51
ReactServerDOMServer = require('react-server-dom-webpack/server.browser');
52
ReactServerDOMClient = require('react-server-dom-webpack/client');
53
use = React.experimental_use;
54
+ cache = React.experimental_cache;
55
});
56
57
async function render(Component) {
@@ -96,6 +98,27 @@ describe('ReactFetch', () => {
98
expect(fetchCount).toBe(2);
99
});
100
101
+ // @gate enableFetchInstrumentation && enableCache
102
+ it('can dedupe cache in micro tasks', async () => {
103
+ const cached = cache(async () => {
104
+ fetchCount++;
105
+ return 'world';
106
+ });
107
+ async function getData() {
108
+ const r1 = await fetch('hello');
109
+ const t1 = await r1.text();
110
+ const t2 = await cached();
111
+ return t1 + ' ' + t2;
112
+ }
113
+ function Component() {
114
+ return use(getData());
115
+ }
116
+ expect(await render(Component)).toMatchInlineSnapshot(
117
+ `"GET hello [] world"`,
118
+ );
119
+ expect(fetchCount).toBe(2);
120
+ });
121
+
122
// @gate enableFetchInstrumentation && enableCache
123
it('can dedupe fetches using Request and not', async () => {
124
function Component() {