From d59159df17c6dca3eec26cb7a5db99cd38c1f567 Mon Sep 17 00:00:00 2001 From: Christian Falch Date: Wed, 14 May 2025 10:11:03 -0700 Subject: [PATCH] fix adding children (#51213) Summary: See https://github.com/facebook/react-native/issues/51212 - children aren't updated correctly in an old arch native view using the interop layer under Fabric. This is caused by the mountChildComponentView method not updating the view, only adding the new view to a list that will be used on the next update to mount the child. This commit fixes this by adding the same pattern as in unmountChildComponentView where children are inserted directly if the underlying paperview is available in the adapter - otherwise it uses the mounting list as before. #Closes 51212 bypass-github-export-checks ## Changelog: [IOS] [FIXED] - fixed adding child views to a native view using the interop layer Pull Request resolved: https://github.com/facebook/react-native/pull/51213 Test Plan: **Previous output**: **After fix**: Reviewed By: sammy-SC Differential Revision: D74471278 Pulled By: cipolleschi fbshipit-source-id: 798f9e7be389359bd6e3aa1b6a6e9fb799fcb369 --- ...CTLegacyViewManagerInteropComponentView.mm | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm b/packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm index 0c5a3f131cb..2373e72215e 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm @@ -170,10 +170,24 @@ static NSString *const kRCTLegacyInteropChildIndexKey = @"index"; - (void)mountChildComponentView:(UIView *)childComponentView index:(NSInteger)index { - [_viewsToBeMounted addObject:@{ - kRCTLegacyInteropChildIndexKey : [NSNumber numberWithInteger:index], - kRCTLegacyInteropChildComponentKey : childComponentView - }]; + if (_adapter && index == _adapter.paperView.reactSubviews.count) { + // This is a new child view that is being added to the end of the children array. + // After the children is added, we need to call didUpdateReactSubviews to make sure that it is rendered. + // Without this change, the new child will not be rendered right away because the didUpdateReactSubviews is not + // called and the `finalizeUpdate` is not invoked. + if ([childComponentView isKindOfClass:[RCTLegacyViewManagerInteropComponentView class]]) { + UIView *target = ((RCTLegacyViewManagerInteropComponentView *)childComponentView).contentView; + [_adapter.paperView insertReactSubview:target atIndex:index]; + } else { + [_adapter.paperView insertReactSubview:childComponentView atIndex:index]; + } + [_adapter.paperView didUpdateReactSubviews]; + } else { + [_viewsToBeMounted addObject:@{ + kRCTLegacyInteropChildIndexKey : [NSNumber numberWithInteger:index], + kRCTLegacyInteropChildComponentKey : childComponentView + }]; + } } - (void)unmountChildComponentView:(UIView *)childComponentView index:(NSInteger)index