diff --git a/packages/react-native/Libraries/Modal/Modal.js b/packages/react-native/Libraries/Modal/Modal.js index 9750d2e5be31d3..a3b118b2e79326 100644 --- a/packages/react-native/Libraries/Modal/Modal.js +++ b/packages/react-native/Libraries/Modal/Modal.js @@ -173,7 +173,13 @@ function confirmProps(props: Props) { } } -class Modal extends React.Component { +// Create a state to track whether the Modal is rendering or not. +// This is the only prop that controls whether the modal is rendered or not. +type State = { + isRendered: boolean, +}; + +class Modal extends React.Component { static defaultProps: {|hardwareAccelerated: boolean, visible: boolean|} = { visible: true, hardwareAccelerated: false, @@ -190,6 +196,9 @@ class Modal extends React.Component { confirmProps(props); } this._identifier = uniqueModalIdentifier++; + this.state = { + isRendered: props.visible === true, + }; } componentDidMount() { @@ -199,7 +208,11 @@ class Modal extends React.Component { 'modalDismissed', event => { if (event.modalID === this._identifier && this.props.onDismiss) { - this.props.onDismiss(); + this.setState({isRendered: false}, () => { + if (this.props.onDismiss) { + this.props.onDismiss(); + } + }); } }, ); @@ -212,14 +225,27 @@ class Modal extends React.Component { } } - componentDidUpdate() { + componentDidUpdate(prevProps: Props) { + if (prevProps.visible === false && this.props.visible === true) { + this.setState({isRendered: true}); + } + if (__DEV__) { confirmProps(this.props); } } + // Helper function to encapsulate platform specific logic to show or not the Modal. + _shouldShowModal(): boolean { + if (Platform.OS === 'ios') { + return this.props.visible === true || this.state.isRendered === true; + } + + return this.props.visible === true; + } + render(): React.Node { - if (this.props.visible !== true) { + if (!this._shouldShowModal()) { return null; } @@ -244,6 +270,17 @@ class Modal extends React.Component { this.props.children ); + const onDismiss = () => { + // OnDismiss is implemented on iOS only. + if (Platform.OS === 'ios') { + this.setState({isRendered: false}, () => { + if (this.props.onDismiss) { + this.props.onDismiss(); + } + }); + } + }; + return ( { hardwareAccelerated={this.props.hardwareAccelerated} onRequestClose={this.props.onRequestClose} onShow={this.props.onShow} - onDismiss={() => { - if (this.props.onDismiss) { - this.props.onDismiss(); - } - }} + onDismiss={onDismiss} visible={this.props.visible} statusBarTranslucent={this.props.statusBarTranslucent} identifier={this._identifier}