Home > Mobile >  React native 3 dots menu for each Card item
React native 3 dots menu for each Card item

Time:01-06

I'm trying to add a 3 dots menu for each item on my screen. I have added the menu but when I click one of the menus, all of them are opened.

Here is my screen;

<ScrollView style={styles.screen}>
    <Title style={styles.pageHeader}>
      Lütfen Adres Seçiniz
    </Title>
    <Button style={styles.addButton} icon="plus" mode="contained" onPress={() => {navigation.navigate("Yeni Adres", {
        })}}>
      Yeni Adres Ekle
    </Button>
      
      <View>

      {address_data.map((address) => (
        <TouchableOpacity onPress={() => {navigation.navigate("Ürünler", {
          "address_id": address
        })}}>
        <View>
        <CardPrivate key={address.id}>

          <Card.Title
          title={address.name}
          subtitle={address.town}
          left={(props) => <Avatar.Icon {...props} icon="home" />}
          
          
          right={(props) => 
            <Menu
                visible={visible}
                onDismiss={closeMenu}
                anchor={ <IconButton {...props} icon="dots-vertical" onPress={openMenu}></IconButton>}>
                <Menu.Item onPress={() => {}} title="Düzenle" />
                <Divider style={{height:1,color:"black",width:"100%"}} />
                <Menu.Item onPress={() => {}} title="Sil" />
            </Menu>}
          />
          <Divider style={{height:2,color:"black",width:"100%"}} />
          <View style={styles.textWrapper}>
          
          <Text>{address.neighborhood}</Text>
          <Text>{address.detail}</Text>
          </View>
        </CardPrivate>
        </View>
        </TouchableOpacity>
      ))}

      </View>
    </ScrollView>

Here is my issues screenshot; enter image description here

I need to open the exact item's menu when I click the 3 dots button. How can I fix this?

Thanks.

CodePudding user response:

you are using the same state for each menu I think that’s why every menu is opening and closing simultaneously. create a wrapper for Menu like following then each menuWrapper will have its own visible state.

export default function MenuWrapper(props) {
  const [visible, setVisible] = useState(false);
  const closeMenu = () => setVisible(false);
  const openMenu = () => setVisible(true);
  return (
    <Menu
      visible={visible}
      onDismiss={closeMenu}
      anchor={
        <IconButton
          {...props}
          icon="dots-vertical"
          onPress={openMenu}
        ></IconButton>
      }
    >
      <Menu.Item onPress={() => {}} title="Düzenle" />
      <Divider style={{ height: 1, color: "black", width: "100%" }} />
      <Menu.Item onPress={() => {}} title="Sil" />
    </Menu>
  );
}

then use MenuWrapper inside your component like following sample code

  {address_data.map((address) => (
  
    <CardPrivate key={address.id}>

      <Card.Title
      title={address.name}
      subtitle={address.town}
      left={(props) => <Avatar.Icon {...props} icon="home" />}

      
      right={(props) => 
        <MenuWrapper {...props} />}
      />
      <Divider style={{height:2,color:"black",width:"100%"}} />
      <View style={styles.textWrapper}>
      
      <Text>{address.neighborhood}</Text>
      <Text>{address.detail}</Text>
      </View>
    </CardPrivate>
  ))}

 

CodePudding user response:

I don't see where your visible state is but I am pretty sure you have declared it in your parent component (in your screen) not in the card component, so you have only one visible state for all the cards you have. You need to move that state in your card component so it would create one visible state for each of the cards, so you could open the menus individually for each cards.

  •  Tags:  
  • Related