It turns out that in React Native there's no proper way to show Modal on top of the Modal.
There's some hack how to achieve this and that's exactly the way how I implemented it in my project. But there's another issue: when I dismiss parent modal app got frozen(on IOS, didn't check Android, but I need both platforms to be working) and parent modal remain opened and you have to force close the app to unblock UI
Code:
import React, { Component } from 'react';
import { Modal, View, TouchableHighlight, Text } from 'react-native';
class MultipleModal extends Component {
state = {
parentModalVisible: false,
childModalVisible: false,
};
closeOpenModal = (parentModalVisible) => {
this.setState({
parentModalVisible,
childModalVisible: parentModalVisible,
});
};
renderModals() {
const { parentModalVisible, childModalVisible } = this.state;
return (
<Modal
visible={parentModalVisible}
transparent={false}
animationType={'none'}
onRequestClose={() => this.closeOpenModal(false)}
>
<View style={{ flex: 1, backgroundColor: 'red' }} />
<Modal
visible={childModalVisible}
transparent={false}
animationType={'none'}
onRequestClose={() => this.closeOpenModal(false)}
>
<View style={{ flex: 1, backgroundColor: 'green' }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableHighlight
style={{ width: 100, height: 40, justifyContent: 'center', alignItems: 'center', backgroundColor: 'lightblue' }}
onPress={() => this.closeOpenModal(false)}
>
<Text>Close Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
</Modal>
);
}
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableHighlight
style={{ width: 100, height: 40, justifyContent: 'center', alignItems: 'center', backgroundColor: 'lightblue' }}
onPress={() => this.closeOpenModal(true)}
>
<Text>Open Modal</Text>
</TouchableHighlight>
</View>
{this.renderModals()}
</View>
);
}
}
export default MultipleModal;
The question is what is proper way to dismiss multiple modals? Because currently to avoid this issue I have to close modals asynchronously, first child and then parent which a bit painful and adds complexity to the code and possible issues:
closeModal = () => {
// Dismiss child
this.setState({ childModalVisible: false }, () => {
// Dismiss parent, but add requestAnimationFrame to prevent app from being frozen
requestAnimationFrame(() => {
this.setState({ parentModalVisible: false });
});
});
};