diff --git a/packages/react-dom/src/server/ReactDOMServerFormatConfig.js b/packages/react-dom/src/server/ReactDOMServerFormatConfig.js
index 1b2bbc28f6669..78e909cff610c 100644
--- a/packages/react-dom/src/server/ReactDOMServerFormatConfig.js
+++ b/packages/react-dom/src/server/ReactDOMServerFormatConfig.js
@@ -168,17 +168,17 @@ export function getChildFormatContext(
return parentContext;
}
-// This object is used to lazily reuse the ID of the first generated node, or assign one.
-// We can't assign an ID up front because the node we're attaching it to might already
-// have one. So we need to lazily use that if it's available.
-export type SuspenseBoundaryID = {
- formattedID: null | PrecomputedChunk,
-};
+export type SuspenseBoundaryID = null | PrecomputedChunk;
+
+export const UNINITIALIZED_SUSPENSE_BOUNDARY_ID: SuspenseBoundaryID = null;
-export function createSuspenseBoundaryID(
+export function assignSuspenseBoundaryID(
responseState: ResponseState,
): SuspenseBoundaryID {
- return {formattedID: null};
+ const generatedID = responseState.nextSuspenseID++;
+ return stringToPrecomputedChunk(
+ responseState.boundaryPrefix + generatedID.toString(16),
+ );
}
export type OpaqueIDType = string;
@@ -201,50 +201,13 @@ function encodeHTMLTextNode(text: string): string {
return escapeTextForBrowser(text);
}
-function assignAnID(
- responseState: ResponseState,
- id: SuspenseBoundaryID,
-): PrecomputedChunk {
- // TODO: This approach doesn't yield deterministic results since this is assigned during render.
- const generatedID = responseState.nextSuspenseID++;
- return (id.formattedID = stringToPrecomputedChunk(
- responseState.boundaryPrefix + generatedID.toString(16),
- ));
-}
-
-const dummyNode1 = stringToPrecomputedChunk('');
-
-function pushDummyNodeWithID(
- target: Array,
- responseState: ResponseState,
- assignID: SuspenseBoundaryID,
-): void {
- const id = assignAnID(responseState, assignID);
- target.push(dummyNode1, id, dummyNode2);
-}
-
-export function pushEmpty(
- target: Array,
- responseState: ResponseState,
- assignID: null | SuspenseBoundaryID,
-): void {
- if (assignID !== null) {
- pushDummyNodeWithID(target, responseState, assignID);
- }
-}
-
const textSeparator = stringToPrecomputedChunk('');
export function pushTextInstance(
target: Array,
text: string,
responseState: ResponseState,
- assignID: null | SuspenseBoundaryID,
): void {
- if (assignID !== null) {
- pushDummyNodeWithID(target, responseState, assignID);
- }
if (text === '') {
// Empty text doesn't have a DOM node representation and the hydration is aware of this.
return;
@@ -514,30 +477,6 @@ function pushAttribute(
const endOfStartTag = stringToPrecomputedChunk('>');
const endOfStartTagSelfClosing = stringToPrecomputedChunk('/>');
-const idAttr = stringToPrecomputedChunk(' id="');
-const attrEnd = stringToPrecomputedChunk('"');
-
-function pushID(
- target: Array,
- responseState: ResponseState,
- assignID: SuspenseBoundaryID,
- existingID: mixed,
-): void {
- if (
- existingID !== null &&
- existingID !== undefined &&
- (typeof existingID === 'string' || typeof existingID === 'object')
- ) {
- // We can reuse the existing ID for our purposes.
- assignID.formattedID = stringToPrecomputedChunk(
- escapeTextForBrowser(existingID),
- );
- } else {
- const encodedID = assignAnID(responseState, assignID);
- target.push(idAttr, encodedID, attrEnd);
- }
-}
-
function pushInnerHTML(
target: Array,
innerHTML,
@@ -598,7 +537,6 @@ function pushStartSelect(
target: Array,
props: Object,
responseState: ResponseState,
- assignID: null | SuspenseBoundaryID,
): ReactNodeList {
if (__DEV__) {
checkControlledValueProps('select', props);
@@ -651,9 +589,6 @@ function pushStartSelect(
}
}
}
- if (assignID !== null) {
- pushID(target, responseState, assignID, props.id);
- }
target.push(endOfStartTag);
pushInnerHTML(target, innerHTML, children);
@@ -693,7 +628,6 @@ function pushStartOption(
props: Object,
responseState: ResponseState,
formatContext: FormatContext,
- assignID: null | SuspenseBoundaryID,
): ReactNodeList {
const selectedValue = formatContext.selectedValue;
@@ -776,10 +710,6 @@ function pushStartOption(
target.push(selectedMarkerAttribute);
}
- if (assignID !== null) {
- pushID(target, responseState, assignID, props.id);
- }
-
target.push(endOfStartTag);
pushInnerHTML(target, innerHTML, children);
return children;
@@ -789,7 +719,6 @@ function pushInput(
target: Array,
props: Object,
responseState: ResponseState,
- assignID: null | SuspenseBoundaryID,
): ReactNodeList {
if (__DEV__) {
checkControlledValueProps('input', props);
@@ -883,10 +812,6 @@ function pushInput(
pushAttribute(target, responseState, 'value', defaultValue);
}
- if (assignID !== null) {
- pushID(target, responseState, assignID, props.id);
- }
-
target.push(endOfStartTagSelfClosing);
return null;
}
@@ -895,7 +820,6 @@ function pushStartTextArea(
target: Array,
props: Object,
responseState: ResponseState,
- assignID: null | SuspenseBoundaryID,
): ReactNodeList {
if (__DEV__) {
checkControlledValueProps('textarea', props);
@@ -952,10 +876,6 @@ function pushStartTextArea(
value = defaultValue;
}
- if (assignID !== null) {
- pushID(target, responseState, assignID, props.id);
- }
-
target.push(endOfStartTag);
// TODO (yungsters): Remove support for children content in