1

I started to learn React Native lately and I'm trying to build my first app, but i'm facing this issue and I don't know how to solve it, I used library React Native Elements and ListItem.Accordion and I create this element:

{meals.map((item, index) => {
        return (
          <ListItem.Accordion 
          theme={{ colors: { primary: "#4169e1" } }}
          style={tw`px-3 rounded py-3 text-white`}
          containerStyle={{ backgroundColor: "#000000", borderRadius: "10px" }}
          content={
            <>
              <Text style={tw`text-5xl mr-2`}>☀️</Text>
              <ListItem.Content>
                <ListItem.Title style={tw`font-bold text-white`}>{item.title}</ListItem.Title>
                <Text style={tw`text-white`}>480 calories</Text>
              </ListItem.Content>
            </>
          }
          key={index}
          index={index}
          noRotation
          isExpanded={expanded}
          icon={
            <Icon
              style={tw`mt-3 p-2`}
              size={35}
              name="add-circle-outline"
              color="white"
              type="material"
            />
          }
          onPress={() => {
            setExpanded(!expanded);
          }}
        >
          <ListItem
            containerStyle={{ backgroundColor: "#000000", borderRadius: "10px" }}
            style={tw`px-3 mt-[-25]`}
            onPress={() => console.log("hi")}
            bottomDivider
          >
            <ListItem.Content>
              <ListItem.Title>
                <Divider width={1} style={tw`w-full`} />
                <View style={tw`justify-around items-center flex-row w-full`}>
                  <View>
                    <Text style={tw`text-gray-400`}>Fats</Text>
                    <Text style={tw`font-bold text-white`}>28.4</Text>
                  </View>
                  <View>
                    <Text style={tw`text-gray-400`}>Carbs</Text>
                    <Text style={tw`font-bold text-white`}>42.32</Text>
                  </View>
                  <View>
                    <Text style={tw`text-gray-400`}>Prot</Text>
                    <Text style={tw`font-bold text-white`}>60,45</Text>
                  </View>
                  <View>
                    <Text style={tw`text-gray-400`}>RDC</Text>
                    <Text style={tw`font-bold text-white`}>12%</Text>
                  </View>
                </View>
              </ListItem.Title>
              <ListItem.Subtitle style={tw`p-2`}>
                <View style={tw`py-3`}>
                  <View
                    style={tw`flex-row py-5 items-center justify-between w-full`}
                  >
                    <View style={tw`flex-row ml-2`}>
                      <Icon
                        name="restaurant-menu"
                        size={50}
                        color="white"
                        type="material"
                      />
                      <View style={tw`ml-3 justify-center`}>
                        <Text style={tw`font-bold text-white`}>Pepperoni Sandwich</Text>
                        <Text style={tw`text-white`}>2 pieces</Text>
                      </View>
                    </View>
                    <Icon name="edit" size={30} color="white" type="material" />
                  </View>
                </View>
              </ListItem.Subtitle>
            </ListItem.Content>
          </ListItem>
        </ListItem.Accordion>
        )
      })}
    </View>
  );
};

When I press, all items are expanded, when I want to achieve is displaying only the item that I select, can anyone give me some advice please? Thanks in advance :)

1
  • If you have a unique identifier on the item you could instead of a boolean value use an array with that identifier based on if its in the list or not open the accordion
    – RubenSmn
    Commented Jan 9, 2023 at 13:34

1 Answer 1

1

Take a look at what you're doing here:

isExpanded={expanded}

You have one boolean value to indicate whether any and all lists are "expanded". A boolean value has exactly two states, true or false. So your list has exactly two states, all expanded or all collapsed.

Instead, store these states as multiple boolean values. If you can modify the meals array, that would be the ideal place to put it as an additional property on the objects in that array. So you might instead have this:

isExpanded={item.expanded}

And update it with something like this:

onPress={() => {
  setMeals(meals.map(m =>
    m.id === item.id ?
    {...m, expanded: !m.expanded} :
    m
  ));
}}

Note of course that this is all based on assumptions about your meals array (such as having an id on items) and is for illustration purposes only. The idea here is that each object in the meals array has an expanded property, and the event handler simply updates that property for the specific object being used here.


Alternatively you could keep the list of "expanded items" in a separate array. Keeping two arrays synchronized in terms of length and sorting can be difficult, but you could just have an array of "currently expanded items":

const [expandedItems, setExpandedItems] = useState([]);

Then just add/remove from that array. So to use it you'd do this:

isExpanded={expandedItems.includes(item.id)}

And you'd update it something like this:

onPress={() => {
  if (isExpanded.includes(item.id)) {
    setIsExpanded(isExpanded.filter(i => i !== item.id));
  } else {
    setIsExpanded([...isExpanded, item.id]);
  }
}}

The idea here is to just have an array of ID values indicating which elements of the list are "expanded". And you'd remove it from the list to collapse or add it to the list to expand.


Any way you structure it, the overall concept is still the same. In order to track the states of these individual elements separately, you need to have separate values for them.

1
  • Work like a charm! 🙏🏽 Thank you very much, and I really appreciated explanation. Have a good day!! 😊
    – reactLover
    Commented Jan 9, 2023 at 14:31

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.