Modal does not appear on list item click

Viewed 91

I am trying to display a modal when a list item is clicked. I set the state to false initially, then when a list item is clicked it sets the setModalVisible state to true and the modal should display. However, even though the state is true, checked by debugging, the modal does not display.

Initial State

this.state = {
      setModalVisible: false,
    };

Render List Item and toggle onPress

renderItem(item) {
    return (
      <ListItem bottomDivider={true} 
      onPress={() => this.showModal(item)}>
        <View style={{flex: 1}} margin={5}>
          <Avatar margin={5} rounded source={{uri: item.logo_url}} />
          <View style={{flexDirection: 'row'}}>
            <Text margin={50}>{item.rank}</Text>
            <Text margin={50} style={styles.cryptoTitle}>
              {item.name}
            </Text>
            <Text style={styles.cryptoPrice}> {'$' + item.price} </Text>
          </View>
        </View>
      </ListItem>
    );
  }

Show Modal Function

showModal(item) {
    this.setState({setModalVisible: true});
    return (
      <View>
        <Modal
          animationType="slide"
          visible={this.state.setModalVisible}
          onRequestClose={() => {
            this.setState({setModalVisible: false});
          }}>
          <Text> Modal is Visible !</Text>
        </Modal>
      </View>
    );
  }
2 Answers

You did not add the Modal in the Item. Returning the modal inside the onPress method would not add it to the tree:

renderItem(item) {
    return (
    <View>
      <ListItem bottomDivider={true} 
      onPress={() => this.showModal(item)}>
        <View style={{flex: 1}} margin={5}>
          <Avatar margin={5} rounded source={{uri: item.logo_url}} />
          <View style={{flexDirection: 'row'}}>
            <Text margin={50}>{item.rank}</Text>
            <Text margin={50} style={styles.cryptoTitle}>
              {item.name}
            </Text>
            <Text style={styles.cryptoPrice}> {'$' + item.price} </Text>
          </View>
        </View>
      </ListItem>
         {this.state.setModalVisible ? <Modal // put the modal somewhere suitable
          animationType="slide"
          visible={this.state.setModalVisible}
          onRequestClose={() => {
            this.setState({setModalVisible: false});
          }}>
          <Text> Modal is Visible !</Text>
        </Modal> : null}
    </View>
    );
  }

Then the showModal simply updates the state:

showModal(item) {
    this.setState({setModalVisible: true});
}

First, the callback passed to onPress will not render the jsx you are returning.

The best approach is to update the state and based on the new one, render items

showModal(item) {
    this.setState({ selectedItem : item });
}
// render the modal somewhere in the parent component

<View>
 <List
 />
 {selectedItem && (
   <Modal
     animationType="slide"
     visible={!!this.state.selectedItem}
     onRequestClose={() => this. setState({ selectedItem : null})}>
          <Text> Modal is Visible !</Text>
   </Modal>
 )}
</View>

Related