最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - react native modal always visible - Stack Overflow

programmeradmin2浏览0评论

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.

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.

Share Improve this question asked Jul 30, 2019 at 17:56 Jithin VargheseJithin Varghese 2,2284 gold badges31 silver badges61 bronze badges 1
  • You may also checkout this one when using expo and web view: github.com/Dekoruma/react-native-web-modal/tree/master/packages/… – Kurt Lagerbier Commented Oct 13, 2020 at 17:59
Add a comment  | 

6 Answers 6

Reset to default 3

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>
      );
    }
}

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

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
      }
    });
 }

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>
);

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});
}

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.

发布评论

评论列表(0)

  1. 暂无评论