skip to Main Content

I have a multiple Pressable component. How can I make it that when I clicked on the Motorcycle pressable, the check icon would be shown beside it and if on the Tricycle Pressable, the check icon would be shown beside it and the one on the Motorcycle icon will be gone.

enter image description here

I have tried creating a state but it simultaneously set all icons in place. Here is the code:

  const [checkIcon, setCheckIcon] = useState(false)

<Pressable
            style={({ pressed }) => [{ opacity: pressed ? 0.4 : 1 }, styles.modalField]}
              onPress={() => setCheckIcon(true)}
            >
              <Image source={require("../assets/motorcycle.png")} style={styles.modalFieldImage} />
              <View style={styles.modalFieldVehicleNameContainer}>
                <Text style={styles.modalFieldText}>Motorcycle</Text>
                <Text style={styles.modalFieldTextDescription}>Cheapest option perfect for small-sized items</Text>
                <Text style={styles.modalFieldTextDescription}>Up to 20 kg</Text>
              </View>
              {
                checkIcon === true ? <Icon name="check" type="font-awesome-5" size={hp("3%")} color="#322C6A" style={styles.modalFieldIcon} /> : null
              }
            </Pressable>

            <Pressable
              style={({ pressed }) => [{ opacity: pressed ? 0.4 : 1 }, styles.modalField]}
              onPress={() => setCheckIcon(true)}
            >
              <Image source={require("../assets/tricycle.png")} style={styles.modalFieldImage} />
              <View style={styles.modalFieldVehicleNameContainer}>
                <Text style={styles.modalFieldText}>Tricycle</Text>
                <Text style={styles.modalFieldTextDescription}>Perfect for multiple medium-sized items</Text>
                <Text style={styles.modalFieldTextDescription}>Up to 70 kg</Text>
              </View>
              {
                checkIcon === true ? <Icon name="check" type="font-awesome-5" size={hp("3%")} color="#322C6A" style={styles.modalFieldIcon} /> : null
              }
            </Pressable>

            <Pressable
              style={({ pressed }) => [{ opacity: pressed ? 0.4 : 1 }, styles.modalField]}
              onPress={() => setCheckIcon(true)}
            >
              <Image source={require("../assets/sedan.png")} style={styles.modalFieldImage} />
              <View style={styles.modalFieldVehicleNameContainer}>
                <Text style={styles.modalFieldText}>Sedan Car</Text>
                <Text style={styles.modalFieldTextDescription}>Good for cakes and multiple small to medium-sized items</Text>
                <Text style={styles.modalFieldTextDescription}>Up to 200 kg</Text>
              </View>
              {
                checkIcon === true ? <Icon name="check" type="font-awesome-5" size={hp("3%")} color="#322C6A" style={styles.modalFieldIcon} /> : null
              }
            </Pressable>

2

Answers


  1. create Vehicle item array like
    vehicle:[ image:'put your imageUrl', name:'', description:'', clickStatus:true ]

    then use map method to display all array item and
    when you click on any item update your array with clickStatus key
    pressable item true and other two item false and display Check Icon based on true or false

    Login or Signup to reply.
  2. Here is an simple example, using a index state to log down which item is selected by user.

    Since your list can be generated dynamically, so you may use an array to store all the parameters for rendering and use map() to render one by one.

    const [optionArray, setOptionArray] = useState([
        {
          title: "Motorcycle",
          desc1: "Cheapest option perfect for small-sized items",
          desc2: "Up to 20 kg",
          img: "../assets/motorcycle.png",
        },
        {
          title: "Tricycle",
          desc1: "Perfect for multiple medium-sized items",
          desc2: "Up to 70 kg",
          img: "../assets/tricycle.png"
        },
        {
          title: "Sedan Car",
          desc1: "Good for cakes and multiple small to medium-sized items",
          desc2: "Up to 200 kg",
          img: "../assets/sedan.png",
        }
      ]);
      const [selectedIndex, setSelectedIndex] = useState(-1);   //Nothing is selected with initial render
    
      const ListItem = ({option, index}) =>{
        return(
          <Pressable
            style={({ pressed }) => [{ opacity: pressed ? 0.4 : 1 }, styles.modalField]}
            onPress={() => setSelectedIndex(index)}
          >
            <Image source={option.img} style={styles.modalFieldImage} />
            <View style={styles.modalFieldVehicleNameContainer}>
              <Text style={styles.modalFieldText}>{option.title}</Text>
              <Text style={styles.modalFieldTextDescription}>{option.desc1}</Text>
              <Text style={styles.modalFieldTextDescription}>{option.desc2}</Text>
            </View>
            {
              index === selectedIndex && <Icon name="check" type="font-awesome-5" size={hp("3%")} color="#322C6A" style={styles.modalFieldIcon} />
            }
          </Pressable>
        )
      }
    
      return(
        <View>
          {
            optionArray.map((option, index) => 
              <ListItem option={option} index={index} />
            )
          }
        </View>
      )
    

    Also answer by Hardik prajapati is another solution too. That method will not affect the result when the data list is sorted in runtime. But large object modification will trigger re-render for components which may lead to performance issue in some case.

    Therefore, you can select different approach for your case.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search