Skip to content

Commit

Permalink
Fix crash in the interop layer when components emits events as soon a…
Browse files Browse the repository at this point in the history
…s are created (#42743)

Summary:

When working on Mobile Home, we found a component (RNCSafeAreaView) that was going through the interop layer.

The component eits an event as soon as its content view changes, but this is too early: the block that emits the event is still nil at that point in time and that makes the app crash.

There might be other components with similarbehavior, therefore, we are fixing it at the interop layer, setting the props immediately after the component is created.

## Changelog:
[iOS][Fixed] - Immediately set props of Components that goes through the interop layer

Differential Revision: D53230471
  • Loading branch information
cipolleschi authored and facebook-github-bot committed Jan 31, 2024
1 parent 841e00e commit 40c1722
Showing 1 changed file with 18 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ - (void)updateState:(const State::Shared &)state oldState:(const State::Shared &
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask
{
[super finalizeUpdates:updateMask];

BOOL propsUpdated = NO;
if (!_adapter) {
_adapter = [[RCTLegacyViewManagerInteropCoordinatorAdapter alloc] initWithCoordinator:[self _coordinator]
reactTag:self.tag];
Expand All @@ -223,6 +223,14 @@ - (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.

[self _setPropsIfNeededWithUpdateMask:updateMask propsUpdated:propsUpdated];
propsUpdated = YES;

self.contentView = _adapter.paperView;
}

Expand All @@ -247,6 +255,15 @@ - (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask

[_adapter.paperView didUpdateReactSubviews];

[self _setPropsIfNeededWithUpdateMask:updateMask propsUpdated:propsUpdated];
}

- (void)_setPropsIfNeededWithUpdateMask:(RNComponentViewUpdateMask)updateMask propsUpdated:(BOOL)propsUpdated
{
if (propsUpdated) {
return;
}

if (updateMask & RNComponentViewUpdateMaskProps) {
const auto &newProps = static_cast<const LegacyViewManagerInteropViewProps &>(*_props);
[_adapter setProps:newProps.otherProps];
Expand Down

0 comments on commit 40c1722

Please sign in to comment.