Frank Boccia
Frank Boccia

Reputation: 248

Modal does not appear on list item click

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

Upvotes: 3

Views: 281

Answers (2)

Amir MB
Amir MB

Reputation: 3418

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

Upvotes: 2

AngelSalazar
AngelSalazar

Reputation: 3113

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>

Upvotes: 1

Related Questions