Reputation: 2228
I have tried to display a modal on click a button in react native. Initially the modal state is hidden, on click button modal should show.
But now everytime it is visible.
//Login.tsx
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, TextInput, Button, TouchableOpacity, ScrollView } from 'react-native';
import axios from 'axios';
import InvalidUserModal from '../Modal/InvalidUser';
export default class LoginFirst extends Component {
constructor(props) {
super(props);
this.state = {
modalVisible: false
};
}
triggerModal() {
this.setState(prevState => {
return {
modalVisible: true
}
});
}
render() {
return (
<View style={styles.container}>
<Button
onPress = {() => this.triggerModal()}
title = "Open Modal"
color = "orange">
</Button>
<InvalidUserModal
image = '../../../../assets/user.png'
data = 'Krunal'
display = { this.state.modalVisible }
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#0d2c4f',
justifyContent: 'center'
}
});
Modal content
import React, { Component } from 'react';
import { Modal, View, Image, Text, StyleSheet } from 'react-native';
const InvalidUser = (props) => (
<View>
<Modal
visible={props.display}
animationType={'slide'}
onRequestClose={() => console.log('closed')}
>
<View>
<Image
source={props.image}
style={styles.image}
/>
<Text style={ styles.text}>
{props.data}
</Text>
</View>
</Modal>
</View>
);
const styles = StyleSheet.create({
image: {
marginTop: 20,
marginLeft: 90,
height: 200,
width: 200
},
text: {
fontSize: 20,
marginLeft: 150
}
});
export default InvalidUser;
The above code is working fine. The only problem is modal always showing. Never hides. Please have a look on below screen.
Is there anything else to be done in the code. Realy stuck here.
Upvotes: 6
Views: 11627
Reputation: 86
You dont have any trigger points to close your modal which is why once you open it you arent able to close it.
in your login.tsx
toggleModal = () => this.setState({modalVisible: !this.state.modalVisible})
and pass this function to your modal as well
<InvalidUserModal
display = {this.state.modalVisible}
toggleModal = {this.toggleModal}
/>
then your modal content should be set like so:
const InvalidUser = (props) => (
<Modal
visible={props.display}
animationType="slide"
onRequestClose={props.toggleModal} //for android hardware back
>
<View>
<Image
source={props.image}
style={styles.image}
/>
<Text style={ styles.text}>
{props.data}
</Text>
<Button
title="Close"
onPress={props.toggleModal}
/>
</View>
</Modal>
);
Upvotes: 2
Reputation: 409
In my case, I was passing a state property that had not been set to false. For some reason, passing undefined
to the visible
param would make the modal appear.
I fixed it either by setting the default value on the state to false
or using visible={this.state.visible || false}
.
Upvotes: 3
Reputation: 31565
I'm not sure if this will work but here is some things you should try.
View
from the Modal
const InvalidUser = (props) => (
{// <View> removed }
<Modal
visible={props.display}
animationType="slide" {// you don't need {} if it's a string}
onRequestClose={() => console.log('closed')}
>
<View>
<Image
source={props.image}
style={styles.image}
/>
<Text style={ styles.text}>
{props.data}
</Text>
</View>
</Modal>
{// </View> removed }
);
setState
in a better wayIf you only want to set the state to true
, you don't need to know the prevState
.
// inside triggerModal
this.setState({modalVisible: true});
// arrow function
triggerModal = () => {
this.setState({modalVisible: true});
}
render() {
return (
<View style={styles.container}>
<Button
{// avoid creating a new function on every render }
onPress = {this.triggerModal}
title = "Open Modal"
color = "orange">
</Button>
<InvalidUserModal
image = '../../../../assets/user.png'
data = 'Krunal'
display = { this.state.modalVisible }
/>
</View>
);
}
}
Upvotes: 3
Reputation: 3788
you should update your handler as follow if you prefer to update the state through a function rather than an object like you did. also the above two solutions is right in case you update the state as an object.
triggerModal() {
this.setState(prevState => {
return {
modalVisible: !prevState.modalVisible
}
});
}
Upvotes: 2
Reputation: 611
You need a way to close the model, the triggerModal method only sets the model to true it doesn't toggle the model. If you want the model to be toggle-able from the same button then you can change your method instead:
triggerModal() {
this.setState({modalVisible: !this.state.modalVisible});
}
Edit:
You also need to bind your function
<Button
onPress = {() => this.triggerModal.bind(this)}
title = "Open Modal"
color = "orange">
</Button>
If your modal still isn't hiding it isn't a matter of state, your modal could possibly be overlaying your toggle button unintentionally.
Upvotes: 1
Reputation: 21
The property that controls if the modal is visible is
this.props.display
Because the function triggerModal() controls what that value is, you have to edit that to get the modal visibility to change. In your case, it looks like there's no way for triggerModal() to return 'false'. Thus, once started, the modal would never be able to be hidden. A better solution may be:
triggerModal = () => {
this.setState({modalVisible: !this.state.modalVisible});
}
Upvotes: 1