From 4236538cbd36d5bc607b3108df45fc51fc8335db Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 13 Feb 2024 10:51:12 -0800 Subject: [PATCH] Fix dismissal on the Old Architecture Summary: The recent change to make onDismiss work on Fabric broke the Modal on Paper (see [this comment](https://www.internalfb.com/diff/D52959996?dst_version_fbid=236415652884499&transaction_fbid=896066412296150)). This change will fix that behavior. The problem was that we were resetting the `isRendered` state only when the Modal receives the event from the Event emitter AND if it has the `onDismiss` callback set. However, we should hide the component in any case if the ids match, and invoke the onDismiss if it is set. ## Changelog [iOS][Fixed] - Make sure that Modal is dismissed correctly in Paper Reviewed By: janeli-100005636499545 Differential Revision: D53686165 fbshipit-source-id: a1de0b29dca7c099e9fa0282ec80cae9a8fd6bc3 --- packages/react-native/Libraries/Modal/Modal.js | 13 ++++++------- .../React/Views/RCTModalHostViewManager.m | 7 ++++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index a3b118b2e79326..1942d9e567d301 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -207,19 +207,18 @@ class Modal extends React.Component { this._eventSubscription = ModalEventEmitter.addListener( 'modalDismissed', event => { - if (event.modalID === this._identifier && this.props.onDismiss) { - this.setState({isRendered: false}, () => { - if (this.props.onDismiss) { - this.props.onDismiss(); - } - }); - } + this.setState({isRendered: false}, () => { + if (event.modalID === this._identifier && this.props.onDismiss) { + this.props.onDismiss(); + } + }); }, ); } } componentWillUnmount() { + this.setState({isRendered: false}); if (this._eventSubscription) { this._eventSubscription.remove(); } diff --git a/packages/react-native/React/Views/RCTModalHostViewManager.m b/packages/react-native/React/Views/RCTModalHostViewManager.m index 4b9f9ad7267c8f..b0295e05ae4d54 100644 --- a/packages/react-native/React/Views/RCTModalHostViewManager.m +++ b/packages/react-native/React/Views/RCTModalHostViewManager.m @@ -98,8 +98,13 @@ - (void)dismissModalHostView:(RCTModalHostView *)modalHostView dispatch_async(dispatch_get_main_queue(), ^{ if (self->_dismissalBlock) { self->_dismissalBlock([modalHostView reactViewController], viewController, animated, completionBlock); - } else { + } else if (viewController.presentingViewController) { [viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock]; + } else { + // Make sure to call the completion block in case the presenting view controller is nil + // In an internal app we have a use case where a modal presents another view without bein dismissed + // This, somehow, invalidate the presenting view controller and the modal remains always visible. + completionBlock(); } }); }