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 b29cffd89bed13..98bcfa8bc48b36 100644 --- a/packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +++ b/packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm @@ -210,11 +210,20 @@ - (void)updateState:(const State::Shared &)state oldState:(const State::Shared & - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask { [super finalizeUpdates:updateMask]; + __block BOOL propsUpdated = NO; + + __weak __typeof(self) weakSelf = self; + void (^updatePropsIfNeeded)(RNComponentViewUpdateMask) = ^void(RNComponentViewUpdateMask mask) { + __typeof(self) strongSelf = weakSelf; + if (!propsUpdated) { + [strongSelf _setPropsWithUpdateMask:mask]; + propsUpdated = YES; + } + }; if (!_adapter) { _adapter = [[RCTLegacyViewManagerInteropCoordinatorAdapter alloc] initWithCoordinator:[self _coordinator] reactTag:self.tag]; - __weak __typeof(self) weakSelf = self; _adapter.eventInterceptor = ^(std::string eventName, folly::dynamic event) { if (weakSelf) { __typeof(self) strongSelf = weakSelf; @@ -223,6 +232,13 @@ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask eventEmitter.dispatchEvent(eventName, event); } }; + // Set props immediately. This is required to set the initial state of the view. + // In the case where some events are fired in relationship of a change in the frame + // or layout of the view, they will fire as soon as the contentView is set and if the + // event block is nil, the app will crash. + updatePropsIfNeeded(updateMask); + propsUpdated = YES; + self.contentView = _adapter.paperView; } @@ -247,6 +263,11 @@ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask [_adapter.paperView didUpdateReactSubviews]; + updatePropsIfNeeded(updateMask); +} + +- (void)_setPropsWithUpdateMask:(RNComponentViewUpdateMask)updateMask +{ if (updateMask & RNComponentViewUpdateMaskProps) { const auto &newProps = static_cast(*_props); [_adapter setProps:newProps.otherProps];