Skip to content

Commit 1c44437

Browse files
authored
Fix createRoot container signature (#24110)
The internal Container type represents the types of containers that React can support in its internals that deal with containers. This didn't include DocumentFragment which we support specifically for rendering into shadow roots. However, not all types makes sense to pass into the createRoot API. One of those is comment nodes that is deprecated and we don't really fully support. It really only exists for FB legacy. For createRoot it doesn't make sense to pass a Document since that will try to empty the document which removes the HTML tag which doesn't work. Documents can only be passed to hydrateRoot. Conversely I'm not sure we actually support hydrating a shadow root properly so I excluded DocumentFragment from hydrateRoot.
1 parent b075f97 commit 1c44437

File tree

5 files changed

+24
-23
lines changed

5 files changed

+24
-23
lines changed

packages/react-dom/client.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
'use strict';
1111

12-
import type {Container} from './src/client/ReactDOMHostConfig';
1312
import type {ReactNodeList} from 'shared/ReactTypes';
1413
import type {
1514
RootType,
@@ -24,7 +23,7 @@ import {
2423
} from './';
2524

2625
export function createRoot(
27-
container: Container,
26+
container: Element | DocumentFragment,
2827
options?: CreateRootOptions,
2928
): RootType {
3029
if (__DEV__) {
@@ -40,7 +39,7 @@ export function createRoot(
4039
}
4140

4241
export function hydrateRoot(
43-
container: Container,
42+
container: Document | Element,
4443
children: ReactNodeList,
4544
options?: HydrateRootOptions,
4645
): RootType {

packages/react-dom/src/client/ReactDOM.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ const Internals = {
148148
};
149149

150150
function createRoot(
151-
container: Container,
151+
container: Element | DocumentFragment,
152152
options?: CreateRootOptions,
153153
): RootType {
154154
if (__DEV__) {
@@ -163,7 +163,7 @@ function createRoot(
163163
}
164164

165165
function hydrateRoot(
166-
container: Container,
166+
container: Document | Element,
167167
initialChildren: ReactNodeList,
168168
options?: HydrateRootOptions,
169169
): RootType {

packages/react-dom/src/client/ReactDOMComponent.js

+11-11
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ export function checkForUnmatchedText(
259259
}
260260

261261
function getOwnerDocumentFromRootContainer(
262-
rootContainerElement: Element | Document,
262+
rootContainerElement: Element | Document | DocumentFragment,
263263
): Document {
264264
return rootContainerElement.nodeType === DOCUMENT_NODE
265265
? (rootContainerElement: any)
@@ -284,7 +284,7 @@ export function trapClickOnNonInteractiveElement(node: HTMLElement) {
284284
function setInitialDOMProperties(
285285
tag: string,
286286
domElement: Element,
287-
rootContainerElement: Element | Document,
287+
rootContainerElement: Element | Document | DocumentFragment,
288288
nextProps: Object,
289289
isCustomComponentTag: boolean,
290290
): void {
@@ -371,7 +371,7 @@ function updateDOMProperties(
371371
export function createElement(
372372
type: string,
373373
props: Object,
374-
rootContainerElement: Element | Document,
374+
rootContainerElement: Element | Document | DocumentFragment,
375375
parentNamespace: string,
376376
): Element {
377377
let isCustomComponentTag;
@@ -477,7 +477,7 @@ export function createElement(
477477

478478
export function createTextNode(
479479
text: string,
480-
rootContainerElement: Element | Document,
480+
rootContainerElement: Element | Document | DocumentFragment,
481481
): Text {
482482
return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(
483483
text,
@@ -488,7 +488,7 @@ export function setInitialProperties(
488488
domElement: Element,
489489
tag: string,
490490
rawProps: Object,
491-
rootContainerElement: Element | Document,
491+
rootContainerElement: Element | Document | DocumentFragment,
492492
): void {
493493
const isCustomComponentTag = isCustomComponent(tag, rawProps);
494494
if (__DEV__) {
@@ -614,7 +614,7 @@ export function diffProperties(
614614
tag: string,
615615
lastRawProps: Object,
616616
nextRawProps: Object,
617-
rootContainerElement: Element | Document,
617+
rootContainerElement: Element | Document | DocumentFragment,
618618
): null | Array<mixed> {
619619
if (__DEV__) {
620620
validatePropertiesInDevelopment(tag, nextRawProps);
@@ -867,7 +867,7 @@ export function diffHydratedProperties(
867867
tag: string,
868868
rawProps: Object,
869869
parentNamespace: string,
870-
rootContainerElement: Element | Document,
870+
rootContainerElement: Element | Document | DocumentFragment,
871871
isConcurrentMode: boolean,
872872
shouldWarnDev: boolean,
873873
): null | Array<mixed> {
@@ -1200,7 +1200,7 @@ export function diffHydratedText(
12001200
}
12011201

12021202
export function warnForDeletedHydratableElement(
1203-
parentNode: Element | Document,
1203+
parentNode: Element | Document | DocumentFragment,
12041204
child: Element,
12051205
) {
12061206
if (__DEV__) {
@@ -1217,7 +1217,7 @@ export function warnForDeletedHydratableElement(
12171217
}
12181218

12191219
export function warnForDeletedHydratableText(
1220-
parentNode: Element | Document,
1220+
parentNode: Element | Document | DocumentFragment,
12211221
child: Text,
12221222
) {
12231223
if (__DEV__) {
@@ -1234,7 +1234,7 @@ export function warnForDeletedHydratableText(
12341234
}
12351235

12361236
export function warnForInsertedHydratedElement(
1237-
parentNode: Element | Document,
1237+
parentNode: Element | Document | DocumentFragment,
12381238
tag: string,
12391239
props: Object,
12401240
) {
@@ -1252,7 +1252,7 @@ export function warnForInsertedHydratedElement(
12521252
}
12531253

12541254
export function warnForInsertedHydratedText(
1255-
parentNode: Element | Document,
1255+
parentNode: Element | Document | DocumentFragment,
12561256
text: string,
12571257
) {
12581258
if (__DEV__) {

packages/react-dom/src/client/ReactDOMHostConfig.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ export type EventTargetChildElement = {
107107
};
108108
export type Container =
109109
| (Element & {_reactRootContainer?: FiberRoot, ...})
110-
| (Document & {_reactRootContainer?: FiberRoot, ...});
110+
| (Document & {_reactRootContainer?: FiberRoot, ...})
111+
| (DocumentFragment & {_reactRootContainer?: FiberRoot, ...});
111112
export type Instance = Element;
112113
export type TextInstance = Text;
113114
export type SuspenseInstance = Comment & {_reactRetry?: () => void, ...};

packages/react-dom/src/client/ReactDOMRoot.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
* @flow
88
*/
99

10-
import type {Container} from './ReactDOMHostConfig';
1110
import type {MutableSource, ReactNodeList} from 'shared/ReactTypes';
1211
import type {
1312
FiberRoot,
@@ -165,7 +164,7 @@ ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = funct
165164
};
166165

167166
export function createRoot(
168-
container: Container,
167+
container: Element | DocumentFragment,
169168
options?: CreateRootOptions,
170169
): RootType {
171170
if (!isValidContainer(container)) {
@@ -235,8 +234,10 @@ export function createRoot(
235234
);
236235
markContainerAsRoot(root.current, container);
237236

238-
const rootContainerElement =
239-
container.nodeType === COMMENT_NODE ? container.parentNode : container;
237+
const rootContainerElement: Document | Element | DocumentFragment =
238+
container.nodeType === COMMENT_NODE
239+
? (container.parentNode: any)
240+
: container;
240241
listenToAllSupportedEvents(rootContainerElement);
241242

242243
return new ReactDOMRoot(root);
@@ -253,7 +254,7 @@ function scheduleHydration(target: Node) {
253254
ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
254255

255256
export function hydrateRoot(
256-
container: Container,
257+
container: Document | Element,
257258
initialChildren: ReactNodeList,
258259
options?: HydrateRootOptions,
259260
): RootType {
@@ -351,7 +352,7 @@ export function isValidContainerLegacy(node: any): boolean {
351352
);
352353
}
353354

354-
function warnIfReactDOMContainerInDEV(container) {
355+
function warnIfReactDOMContainerInDEV(container: any) {
355356
if (__DEV__) {
356357
if (
357358
container.nodeType === ELEMENT_NODE &&

0 commit comments

Comments
 (0)