Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

react native modal always visible

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.

App screen

Is there anything else to be done in the code. Realy stuck here.

like image 787
Jithin Varghese Avatar asked Jul 30 '19 17:07

Jithin Varghese


2 Answers

I'm not sure if this will work but here is some things you should try.

Remove 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 way

If you only want to set the state to true, you don't need to know the prevState.

// inside triggerModal 
this.setState({modalVisible: true});

Use arrow function for the class properties and avoid mutiple render of an arrow function.

// 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>
      );
    }
}
like image 71
Vencovsky Avatar answered Sep 28 '22 00:09

Vencovsky


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}.

like image 39
Henrique Mazer Avatar answered Sep 27 '22 23:09

Henrique Mazer