@@ -248,7 +248,7 @@ function prepareChildrenArray(childrenArray) {
248248 return childrenArray ;
249249}
250250
251- function prepareChildrenIterable ( childrenArray ) {
251+ function prepareChildrenLegacyIterable ( childrenArray ) {
252252 return {
253253 '@@iterator' : function * ( ) {
254254 // eslint-disable-next-line no-for-of-loops/no-for-of-loops
@@ -259,9 +259,27 @@ function prepareChildrenIterable(childrenArray) {
259259 } ;
260260}
261261
262+ function prepareChildrenModernIterable ( childrenArray ) {
263+ return {
264+ [ Symbol . iterator ] : function * ( ) {
265+ // eslint-disable-next-line no-for-of-loops/no-for-of-loops
266+ for ( const child of childrenArray ) {
267+ yield child ;
268+ }
269+ } ,
270+ } ;
271+ }
272+
262273function testPropsSequence ( sequence ) {
263274 testPropsSequenceWithPreparedChildren ( sequence , prepareChildrenArray ) ;
264- testPropsSequenceWithPreparedChildren ( sequence , prepareChildrenIterable ) ;
275+ testPropsSequenceWithPreparedChildren (
276+ sequence ,
277+ prepareChildrenLegacyIterable ,
278+ ) ;
279+ testPropsSequenceWithPreparedChildren (
280+ sequence ,
281+ prepareChildrenModernIterable ,
282+ ) ;
265283}
266284
267285describe ( 'ReactMultiChildReconcile' , ( ) => {
@@ -311,7 +329,49 @@ describe('ReactMultiChildReconcile', () => {
311329 ) ;
312330 } ) ;
313331
314- it ( 'should reset internal state if removed then readded in an iterable' , ( ) => {
332+ it ( 'should reset internal state if removed then readded in a legacy iterable' , ( ) => {
333+ // Test basics.
334+ const props = {
335+ usernameToStatus : {
336+ jcw : 'jcwStatus' ,
337+ } ,
338+ } ;
339+
340+ const container = document . createElement ( 'div' ) ;
341+ const parentInstance = ReactDOM . render (
342+ < FriendsStatusDisplay
343+ { ...props }
344+ prepareChildren = { prepareChildrenLegacyIterable }
345+ /> ,
346+ container ,
347+ ) ;
348+ let statusDisplays = parentInstance . getStatusDisplays ( ) ;
349+ const startingInternalState = statusDisplays . jcw . getInternalState ( ) ;
350+
351+ // Now remove the child.
352+ ReactDOM . render (
353+ < FriendsStatusDisplay prepareChildren = { prepareChildrenLegacyIterable } /> ,
354+ container ,
355+ ) ;
356+ statusDisplays = parentInstance . getStatusDisplays ( ) ;
357+ expect ( statusDisplays . jcw ) . toBeFalsy ( ) ;
358+
359+ // Now reset the props that cause there to be a child
360+ ReactDOM . render (
361+ < FriendsStatusDisplay
362+ { ...props }
363+ prepareChildren = { prepareChildrenLegacyIterable }
364+ /> ,
365+ container ,
366+ ) ;
367+ statusDisplays = parentInstance . getStatusDisplays ( ) ;
368+ expect ( statusDisplays . jcw ) . toBeTruthy ( ) ;
369+ expect ( statusDisplays . jcw . getInternalState ( ) ) . not . toBe (
370+ startingInternalState ,
371+ ) ;
372+ } ) ;
373+
374+ it ( 'should reset internal state if removed then readded in a modern iterable' , ( ) => {
315375 // Test basics.
316376 const props = {
317377 usernameToStatus : {
@@ -323,7 +383,7 @@ describe('ReactMultiChildReconcile', () => {
323383 const parentInstance = ReactDOM . render (
324384 < FriendsStatusDisplay
325385 { ...props }
326- prepareChildren = { prepareChildrenIterable }
386+ prepareChildren = { prepareChildrenModernIterable }
327387 /> ,
328388 container ,
329389 ) ;
@@ -332,7 +392,7 @@ describe('ReactMultiChildReconcile', () => {
332392
333393 // Now remove the child.
334394 ReactDOM . render (
335- < FriendsStatusDisplay prepareChildren = { prepareChildrenIterable } /> ,
395+ < FriendsStatusDisplay prepareChildren = { prepareChildrenModernIterable } /> ,
336396 container ,
337397 ) ;
338398 statusDisplays = parentInstance . getStatusDisplays ( ) ;
@@ -342,7 +402,7 @@ describe('ReactMultiChildReconcile', () => {
342402 ReactDOM . render (
343403 < FriendsStatusDisplay
344404 { ...props }
345- prepareChildren = { prepareChildrenIterable }
405+ prepareChildren = { prepareChildrenModernIterable }
346406 /> ,
347407 container ,
348408 ) ;
0 commit comments