diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index dd42e81ef667f..42c5bc54405dd 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -1810,18 +1810,45 @@ function renderChildrenArray( for (let i = 0; i < totalChildren; i++) { const node = children[i]; task.treeContext = pushTreeContext(prevTreeContext, totalChildren, i); - if (isArray(node) || getIteratorFn(node)) { - // Nested arrays behave like a "fragment node" which is keyed. - // Therefore we need to add the current index as a parent key. + + // Nested arrays behave like a "fragment node" which is keyed. + // Therefore we need to add the current index as a parent key. + // We first check if the nested nodes are arrays or iterables. + + if (isArray(node)) { const prevKeyPath = task.keyPath; task.keyPath = [task.keyPath, '', childIndex]; - renderNode(request, task, node, i); + renderChildrenArray(request, task, node, i); task.keyPath = prevKeyPath; - } else { - // We need to use the non-destructive form so that we can safely pop back - // up and render the sibling if something suspends. - renderNode(request, task, node, i); + continue; } + + const iteratorFn = getIteratorFn(node); + if (iteratorFn) { + if (__DEV__) { + validateIterable(node, iteratorFn); + } + const iterator = iteratorFn.call(node); + if (iterator) { + let step = iterator.next(); + if (!step.done) { + const prevKeyPath = task.keyPath; + task.keyPath = [task.keyPath, '', childIndex]; + const nestedChildren = []; + do { + nestedChildren.push(step.value); + step = iterator.next(); + } while (!step.done); + renderChildrenArray(request, task, nestedChildren, i); + task.keyPath = prevKeyPath; + } + continue; + } + } + + // We need to use the non-destructive form so that we can safely pop back + // up and render the sibling if something suspends. + renderNode(request, task, node, i); } // Because this context is always set right before rendering every child, we // only need to reset it to the previous value at the very end.