@@ -1004,6 +1004,162 @@ describe('ReactDOMServerHooks', () => {
10041004 ) ;
10051005 } ) ;
10061006
1007+ it ( 'useOpaqueIdentifier identifierPrefix works for server renderer and does not clash' , async ( ) => {
1008+ function ChildTwo ( { id} ) {
1009+ return < div id = { id } > Child Three</ div > ;
1010+ }
1011+ function App ( ) {
1012+ const id = useOpaqueIdentifier ( ) ;
1013+ const idTwo = useOpaqueIdentifier ( ) ;
1014+
1015+ return (
1016+ < div >
1017+ < div aria-labelledby = { id } > Chid One</ div >
1018+ < ChildTwo id = { id } />
1019+ < div aria-labelledby = { idTwo } > Child Three</ div >
1020+ < div id = { idTwo } > Child Four</ div >
1021+ </ div >
1022+ ) ;
1023+ }
1024+
1025+ const containerOne = document . createElement ( 'div' ) ;
1026+ document . body . append ( containerOne ) ;
1027+
1028+ containerOne . innerHTML = ReactDOMServer . renderToString ( < App /> , {
1029+ identifierPrefix : 'one' ,
1030+ } ) ;
1031+
1032+ const containerTwo = document . createElement ( 'div' ) ;
1033+ document . body . append ( containerTwo ) ;
1034+
1035+ containerTwo . innerHTML = ReactDOMServer . renderToString ( < App /> , {
1036+ identifierPrefix : 'two' ,
1037+ } ) ;
1038+
1039+ expect ( document . body . children . length ) . toEqual ( 2 ) ;
1040+ const childOne = document . body . children [ 0 ] ;
1041+ const childTwo = document . body . children [ 1 ] ;
1042+
1043+ expect (
1044+ childOne . children [ 0 ] . children [ 0 ] . getAttribute ( 'aria-labelledby' ) ,
1045+ ) . toEqual ( childOne . children [ 0 ] . children [ 1 ] . getAttribute ( 'id' ) ) ;
1046+ expect (
1047+ childOne . children [ 0 ] . children [ 2 ] . getAttribute ( 'aria-labelledby' ) ,
1048+ ) . toEqual ( childOne . children [ 0 ] . children [ 3 ] . getAttribute ( 'id' ) ) ;
1049+
1050+ expect (
1051+ childOne . children [ 0 ] . children [ 0 ] . getAttribute ( 'aria-labelledby' ) ,
1052+ ) . not . toEqual (
1053+ childOne . children [ 0 ] . children [ 2 ] . getAttribute ( 'aria-labelledby' ) ,
1054+ ) ;
1055+
1056+ expect (
1057+ childOne . children [ 0 ] . children [ 0 ]
1058+ . getAttribute ( 'aria-labelledby' )
1059+ . startsWith ( 'one' ) ,
1060+ ) . toBe ( true ) ;
1061+ expect (
1062+ childOne . children [ 0 ] . children [ 2 ]
1063+ . getAttribute ( 'aria-labelledby' )
1064+ . includes ( 'one' ) ,
1065+ ) . toBe ( true ) ;
1066+
1067+ expect (
1068+ childTwo . children [ 0 ] . children [ 0 ] . getAttribute ( 'aria-labelledby' ) ,
1069+ ) . toEqual ( childTwo . children [ 0 ] . children [ 1 ] . getAttribute ( 'id' ) ) ;
1070+ expect (
1071+ childTwo . children [ 0 ] . children [ 2 ] . getAttribute ( 'aria-labelledby' ) ,
1072+ ) . toEqual ( childTwo . children [ 0 ] . children [ 3 ] . getAttribute ( 'id' ) ) ;
1073+
1074+ expect (
1075+ childTwo . children [ 0 ] . children [ 0 ] . getAttribute ( 'aria-labelledby' ) ,
1076+ ) . not . toEqual (
1077+ childTwo . children [ 0 ] . children [ 2 ] . getAttribute ( 'aria-labelledby' ) ,
1078+ ) ;
1079+
1080+ expect (
1081+ childTwo . children [ 0 ] . children [ 0 ]
1082+ . getAttribute ( 'aria-labelledby' )
1083+ . startsWith ( 'two' ) ,
1084+ ) . toBe ( true ) ;
1085+ expect (
1086+ childTwo . children [ 0 ] . children [ 2 ]
1087+ . getAttribute ( 'aria-labelledby' )
1088+ . startsWith ( 'two' ) ,
1089+ ) . toBe ( true ) ;
1090+ } ) ;
1091+
1092+ it ( 'useOpaqueIdentifier identifierPrefix works for multiple reads on a streaming server renderer' , async ( ) => {
1093+ function ChildTwo ( ) {
1094+ const id = useOpaqueIdentifier ( ) ;
1095+
1096+ return < div id = { id } > Child Two</ div > ;
1097+ }
1098+
1099+ function App ( ) {
1100+ const id = useOpaqueIdentifier ( ) ;
1101+
1102+ return (
1103+ < >
1104+ < div id = { id } > Child One</ div >
1105+ < ChildTwo />
1106+ < div aria-labelledby = { id } > Aria One</ div >
1107+ </ >
1108+ ) ;
1109+ }
1110+
1111+ const container = document . createElement ( 'div' ) ;
1112+ document . body . append ( container ) ;
1113+
1114+ const streamOne = ReactDOMServer . renderToNodeStream ( < App /> , {
1115+ identifierPrefix : 'one' ,
1116+ } ) . setEncoding ( 'utf8' ) ;
1117+ const streamTwo = ReactDOMServer . renderToNodeStream ( < App /> , {
1118+ identifierPrefix : 'two' ,
1119+ } ) . setEncoding ( 'utf8' ) ;
1120+
1121+ const containerOne = document . createElement ( 'div' ) ;
1122+ const containerTwo = document . createElement ( 'div' ) ;
1123+
1124+ streamOne . _read ( 10 ) ;
1125+ streamTwo . _read ( 10 ) ;
1126+
1127+ containerOne . innerHTML = streamOne . read ( ) ;
1128+ containerTwo . innerHTML = streamTwo . read ( ) ;
1129+
1130+ expect ( containerOne . children [ 0 ] . getAttribute ( 'id' ) ) . not . toEqual (
1131+ containerOne . children [ 1 ] . getAttribute ( 'id' ) ,
1132+ ) ;
1133+ expect ( containerTwo . children [ 0 ] . getAttribute ( 'id' ) ) . not . toEqual (
1134+ containerTwo . children [ 1 ] . getAttribute ( 'id' ) ,
1135+ ) ;
1136+ expect ( containerOne . children [ 0 ] . getAttribute ( 'id' ) ) . not . toEqual (
1137+ containerTwo . children [ 0 ] . getAttribute ( 'id' ) ,
1138+ ) ;
1139+ expect (
1140+ containerOne . children [ 0 ] . getAttribute ( 'id' ) . includes ( 'one' ) ,
1141+ ) . toBe ( true ) ;
1142+ expect (
1143+ containerOne . children [ 1 ] . getAttribute ( 'id' ) . includes ( 'one' ) ,
1144+ ) . toBe ( true ) ;
1145+ expect (
1146+ containerTwo . children [ 0 ] . getAttribute ( 'id' ) . includes ( 'two' ) ,
1147+ ) . toBe ( true ) ;
1148+ expect (
1149+ containerTwo . children [ 1 ] . getAttribute ( 'id' ) . includes ( 'two' ) ,
1150+ ) . toBe ( true ) ;
1151+
1152+ expect ( containerOne . children [ 1 ] . getAttribute ( 'id' ) ) . not . toEqual (
1153+ containerTwo . children [ 1 ] . getAttribute ( 'id' ) ,
1154+ ) ;
1155+ expect ( containerOne . children [ 0 ] . getAttribute ( 'id' ) ) . toEqual (
1156+ containerOne . children [ 2 ] . getAttribute ( 'aria-labelledby' ) ,
1157+ ) ;
1158+ expect ( containerTwo . children [ 0 ] . getAttribute ( 'id' ) ) . toEqual (
1159+ containerTwo . children [ 2 ] . getAttribute ( 'aria-labelledby' ) ,
1160+ ) ;
1161+ } ) ;
1162+
10071163 it ( 'useOpaqueIdentifier: IDs match when, after hydration, a new component that uses the ID is rendered' , async ( ) => {
10081164 let _setShowDiv ;
10091165 function App ( ) {
0 commit comments