File tree Expand file tree Collapse file tree 2 files changed +52
-2
lines changed
packages/react-reconciler/src Expand file tree Collapse file tree 2 files changed +52
-2
lines changed Original file line number Diff line number Diff line change @@ -1460,15 +1460,18 @@ function createChildReconciler(
14601460 lanes : Lanes ,
14611461 debugInfo : ReactDebugInfo | null ,
14621462 ) : Fiber | null {
1463- // This function is not recursive.
1463+ // This function is only recursive for Usables/Lazy and not nested arrays.
1464+ // That's so that using a Lazy wrapper is unobservable to the Fragment
1465+ // convention.
14641466 // If the top level item is an array, we treat it as a set of children,
14651467 // not as a fragment. Nested arrays on the other hand will be treated as
14661468 // fragment nodes. Recursion happens at the normal flow.
14671469
14681470 // Handle top level unkeyed fragments as if they were arrays.
14691471 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
14701472 // We treat the ambiguous cases above the same.
1471- // TODO: Let's use recursion like we do for Usable nodes?
1473+ // We don't use recursion here because a fragment inside a fragment
1474+ // is no longer considered "top level" for these purposes.
14721475 const isUnkeyedTopLevelFragment =
14731476 typeof newChild === 'object' &&
14741477 newChild !== null &&
Original file line number Diff line number Diff line change @@ -965,4 +965,51 @@ describe('ReactFragment', () => {
965965 </ > ,
966966 ) ;
967967 } ) ;
968+
969+ it ( 'should preserve state of children when adding a fragment wrapped in Lazy' , async function ( ) {
970+ const ops = [ ] ;
971+
972+ class Stateful extends React . Component {
973+ componentDidUpdate ( ) {
974+ ops . push ( 'Update Stateful' ) ;
975+ }
976+
977+ render ( ) {
978+ return < div > Hello</ div > ;
979+ }
980+ }
981+
982+ const lazyChild = React . lazy ( async ( ) => ( {
983+ default : (
984+ < >
985+ < Stateful key = "a" />
986+ < div key = "b" > World</ div >
987+ </ >
988+ ) ,
989+ } ) ) ;
990+
991+ function Foo ( { condition} ) {
992+ return condition ? < Stateful key = "a" /> : lazyChild ;
993+ }
994+
995+ ReactNoop . render ( < Foo condition = { true } /> ) ;
996+ await waitForAll ( [ ] ) ;
997+
998+ ReactNoop . render ( < Foo condition = { false } /> ) ;
999+ await waitForAll ( [ ] ) ;
1000+
1001+ expect ( ops ) . toEqual ( [ 'Update Stateful' ] ) ;
1002+ expect ( ReactNoop ) . toMatchRenderedOutput (
1003+ < >
1004+ < div > Hello</ div >
1005+ < div > World</ div >
1006+ </ > ,
1007+ ) ;
1008+
1009+ ReactNoop . render ( < Foo condition = { true } /> ) ;
1010+ await waitForAll ( [ ] ) ;
1011+
1012+ expect ( ops ) . toEqual ( [ 'Update Stateful' , 'Update Stateful' ] ) ;
1013+ expect ( ReactNoop ) . toMatchRenderedOutput ( < div > Hello</ div > ) ;
1014+ } ) ;
9681015} ) ;
You can’t perform that action at this time.
0 commit comments