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

This commit is contained in:
Andrew Gadzik
2023-05-03 15:06:10 -04:00
committed by GitHub
parent fa7a447b9c
commit 2c1117a8d0
2 changed files with 23 additions and 1 deletions

View File

@@ -74,7 +74,13 @@ if (enableCache && enableFetchInstrumentation) {
url = resource;
} else {
// Normalize the request.
const request = new Request(resource, options);
// if resource is not a string or a URL (its an instance of Request)
// then do not instantiate a new Request but instead
// reuse the request as to not disturb the body in the event it's a ReadableStream.
const request =
typeof resource === 'string' || resource instanceof URL
? new Request(resource, options)
: resource;
if (
(request.method !== 'GET' && request.method !== 'HEAD') ||
// $FlowFixMe[prop-missing]: keepalive is real

View File

@@ -135,6 +135,22 @@ describe('ReactFetch', () => {
expect(fetchCount).toBe(1);
});
// @gate enableFetchInstrumentation && enableCache
it('can dedupe fetches using URL and not', async () => {
const url = 'http://example.com/';
function Component() {
const response = use(fetch(url));
const text = use(response.text());
const response2 = use(fetch(new URL(url)));
const text2 = use(response2.text());
return text + ' ' + text2;
}
expect(await render(Component)).toMatchInlineSnapshot(
`"GET ${url} [] GET ${url} []"`,
);
expect(fetchCount).toBe(1);
});
it('can opt-out of deduping fetches inside of render with custom signal', async () => {
const controller = new AbortController();
function useCustomHook() {