@samitouri / QOS-React-2 / commits / 2c1117a8d0

Reuse request so that a ReabableStream body does not become disturbed (#26771)

Andrew Gadzik committed May 3, 2023 at 15:06 UTC 2c1117a8d008e34eb77eaaf7b8ef315a38644735
2 files changed +23 -1
packages/react/src/ReactFetch.js
+7 -1
@@ -74,7 +74,13 @@ if (enableCache && enableFetchInstrumentation) {
74 url = resource;
75 } else {
76 // Normalize the request.
77 - const request = new Request(resource, options);
77 + // if resource is not a string or a URL (its an instance of Request)
78 + // then do not instantiate a new Request but instead
79 + // reuse the request as to not disturb the body in the event it's a ReadableStream.
80 + const request =
81 + typeof resource === 'string' || resource instanceof URL
82 + ? new Request(resource, options)
83 + : resource;
84 if (
85 (request.method !== 'GET' && request.method !== 'HEAD') ||
86 // $FlowFixMe[prop-missing]: keepalive is real
packages/react/src/__tests__/ReactFetch-test.js
+16
@@ -135,6 +135,22 @@ describe('ReactFetch', () => {
135 expect(fetchCount).toBe(1);
136 });
137
138 + // @gate enableFetchInstrumentation && enableCache
139 + it('can dedupe fetches using URL and not', async () => {
140 + const url = 'http://example.com/';
141 + function Component() {
142 + const response = use(fetch(url));
143 + const text = use(response.text());
144 + const response2 = use(fetch(new URL(url)));
145 + const text2 = use(response2.text());
146 + return text + ' ' + text2;
147 + }
148 + expect(await render(Component)).toMatchInlineSnapshot(
149 + `"GET ${url} [] GET ${url} []"`,
150 + );
151 + expect(fetchCount).toBe(1);
152 + });
153 +
154 it('can opt-out of deduping fetches inside of render with custom signal', async () => {
155 const controller = new AbortController();
156 function useCustomHook() {