diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index a3b118b2e79..1942d9e567d 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 4b9f9ad7267..b0295e05ae4 100644 --- a/packages/react-native/React/Views/RCTModalHostViewManager.m +++ b/packages/react-native/React/Views/RCTModalHostViewManager.m @@ -98,8 +98,13 @@ RCT_EXPORT_MODULE() 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(); } }); }