@@ -30,6 +30,7 @@ import type {TransitionTypes} from 'react/src/ReactTransitionType.js';
30
30
import { NotPending } from '../shared/ReactDOMFormActions' ;
31
31
32
32
import { getCurrentRootHostContainer } from 'react-reconciler/src/ReactFiberHostContext' ;
33
+ import { runWithFiberInDEV } from 'react-reconciler/src/ReactCurrentFiber' ;
33
34
34
35
import hasOwnProperty from 'shared/hasOwnProperty' ;
35
36
import { checkAttributeStringCoercion } from 'shared/CheckStringCoercion' ;
@@ -43,6 +44,8 @@ export {
43
44
import {
44
45
precacheFiberNode ,
45
46
updateFiberProps ,
47
+ getFiberCurrentPropsFromNode ,
48
+ getInstanceFromNode ,
46
49
getClosestInstanceFromNode ,
47
50
getFiberFromScopeInstance ,
48
51
getInstanceFromNode as getInstanceFromNodeDOMTree ,
@@ -821,10 +824,51 @@ export function appendChild(
821
824
}
822
825
}
823
826
827
+ function warnForReactChildrenConflict ( container : Container ) : void {
828
+ if ( __DEV__ ) {
829
+ if ( ( container : any ) . __reactWarnedAboutChildrenConflict ) {
830
+ return ;
831
+ }
832
+ const props = getFiberCurrentPropsFromNode ( container ) ;
833
+ if ( props !== null ) {
834
+ const fiber = getInstanceFromNode ( container ) ;
835
+ if ( fiber !== null ) {
836
+ if (
837
+ typeof props . children === 'string' ||
838
+ typeof props . children === 'number'
839
+ ) {
840
+ ( container : any ) . __reactWarnedAboutChildrenConflict = true ;
841
+ // Run the warning with the Fiber of the container for context of where the children are specified.
842
+ // We could also maybe use the Portal. The current execution context is the child being added.
843
+ runWithFiberInDEV ( fiber , ( ) => {
844
+ console . error (
845
+ 'Cannot use a ref on a React element as a container to `createRoot` or `createPortal` ' +
846
+ 'if that element also sets "children" text content using React. It should be a leaf with no children. ' +
847
+ "Otherwise it's ambiguous which children should be used." ,
848
+ ) ;
849
+ } ) ;
850
+ } else if ( props . dangerouslySetInnerHTML != null ) {
851
+ ( container : any ) . __reactWarnedAboutChildrenConflict = true ;
852
+ runWithFiberInDEV ( fiber , ( ) => {
853
+ console . error (
854
+ 'Cannot use a ref on a React element as a container to `createRoot` or `createPortal` ' +
855
+ 'if that element also sets "dangerouslySetInnerHTML" using React. It should be a leaf with no children. ' +
856
+ "Otherwise it's ambiguous which children should be used." ,
857
+ ) ;
858
+ } ) ;
859
+ }
860
+ }
861
+ }
862
+ }
863
+ }
864
+
824
865
export function appendChildToContainer (
825
866
container : Container ,
826
867
child : Instance | TextInstance ,
827
868
) : void {
869
+ if ( __DEV__ ) {
870
+ warnForReactChildrenConflict ( container ) ;
871
+ }
828
872
let parentNode : DocumentFragment | Element ;
829
873
if ( container . nodeType === DOCUMENT_NODE ) {
830
874
parentNode = ( container : any ) . body ;
@@ -888,6 +932,9 @@ export function insertInContainerBefore(
888
932
child : Instance | TextInstance ,
889
933
beforeChild : Instance | TextInstance | SuspenseInstance ,
890
934
) : void {
935
+ if ( __DEV__ ) {
936
+ warnForReactChildrenConflict ( container ) ;
937
+ }
891
938
let parentNode : DocumentFragment | Element ;
892
939
if ( container . nodeType === DOCUMENT_NODE ) {
893
940
parentNode = ( container : any ) . body ;
0 commit comments