Skip to content

Commit 2c0a9bc

Browse files
committed
defend against useId call outside of rendering
1 parent 39e8147 commit 2c0a9bc

File tree

3 files changed

+17
-21
lines changed

3 files changed

+17
-21
lines changed

packages/react-client/src/__tests__/ReactFlight-test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,8 @@ describe('ReactFlight', () => {
534534
});
535535
expect(ReactNoop).toMatchRenderedOutput(
536536
<>
537-
<div prop=":$:F1" />
538-
<div prop=":$:F2" />
537+
<div prop=":F1:" />
538+
<div prop=":F2:" />
539539
</>,
540540
);
541541
});
@@ -558,8 +558,8 @@ describe('ReactFlight', () => {
558558
});
559559
expect(ReactNoop).toMatchRenderedOutput(
560560
<>
561-
<div prop=":foo:F1" />
562-
<div prop=":foo:F2" />
561+
<div prop=":fooF1:" />
562+
<div prop=":fooF2:" />
563563
</>,
564564
);
565565
});

packages/react-server/src/ReactFlightHooks.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,14 @@ import type {ReactServerContext} from 'shared/ReactTypes';
1313
import {REACT_SERVER_CONTEXT_TYPE} from 'shared/ReactSymbols';
1414
import {readContext as readContextImpl} from './ReactFlightNewContext';
1515

16-
let currentIndentifierPrefix = '$';
17-
let currentIndentifierCount = 0;
16+
let currentRequest = null;
1817

1918
export function prepareToUseHooksForRequest(request: Request) {
20-
if (request.identifierPrefix) {
21-
currentIndentifierPrefix = request.identifierPrefix;
22-
}
23-
currentIndentifierCount = request.identifierCount;
19+
currentRequest = request;
2420
}
2521

26-
export function resetHooksForRequest(request: Request) {
27-
currentIndentifierPrefix = '$';
28-
request.identifierCount = currentIndentifierCount;
29-
currentIndentifierCount = 0;
22+
export function resetHooksForRequest() {
23+
currentRequest = null;
3024
}
3125

3226
function readContext<T>(context: ReactServerContext<T>): T {
@@ -110,10 +104,12 @@ export function getCurrentCache() {
110104
}
111105

112106
function useId(): string {
113-
return (
114-
':' +
115-
currentIndentifierPrefix +
116-
':F' +
117-
(currentIndentifierCount++).toString(32)
118-
);
107+
if (currentRequest === null) {
108+
throw new Error('useId can only be used while React is rendering.');
109+
}
110+
const prefix = currentRequest.identifierPrefix
111+
? currentRequest.identifierPrefix
112+
: '';
113+
const id = currentRequest.identifierCount++;
114+
return ':' + prefix + 'F' + id.toString(32) + ':';
119115
}

packages/react-server/src/ReactFlightServer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ function performWork(request: Request): void {
851851
} finally {
852852
ReactCurrentDispatcher.current = prevDispatcher;
853853
setCurrentCache(prevCache);
854-
resetHooksForRequest(request);
854+
resetHooksForRequest();
855855
}
856856
}
857857

0 commit comments

Comments
 (0)