How to expand only one collapsible at one time

1.5k views Asked by At

I'm very new to react native. So the problem here now is I want to expand and collapse the view only one item at a time. Currently, every item expands and collapses simultaneously eventhough I only click at one item Any suggestions ? Below is my code and I have attached the screenshot of my screen.

export default function AppCollapsible({ data }: { data: any }) {
  const [collapsed, setCollapsed] = useState(true);
  const [multipeSelect, setMultipleSelect] = useState(false);

  const isExpanded = () => {
    if (collapsed) {
      setCollapsed(false);
    } else {
      setCollapsed(true);
    }
  };

  useEffect(() => {});
  return (
    <View style={styles.listContainer}>
      <TouchableOpacity onPress={isExpanded}>
        <View style={styles.list}>
          <Text style={styles.accName}>Current / Savings</Text>
          <Text style={styles.accValue}>MYR 40,000</Text>

          <View style={styles.imageIcon}>
            <Image
              source={require('ngcc_poc/src/assets/icons/active/ChevronDown.png')}
            />
          </View>
          <Collapsible collapsed={collapsed} align="center">
            <CurrentSavingsCard />
          </Collapsible>
        </View>
      </TouchableOpacity>
      <TouchableOpacity onPress={isExpanded}>
        <View style={styles.list}>
          <Text style={styles.accName}>Fixed Deposit</Text>
          <Text style={styles.accValue}>MYR 180,000</Text>

          <View style={styles.imageIcon}>
            <Image
              source={require('ngcc_poc/src/assets/icons/active/ChevronDown.png')}
            />
          </View>
          <Collapsible collapsed={collapsed} align="center">
            <FixedDeposit />
          </Collapsible>
        </View>
      </TouchableOpacity>
      
    </View>
  );
}

enter image description here

2

There are 2 answers

1
David Leuliette On

It's not a complete answer but as a source of inspiration as @laurenyz suggested you.

You can have a look at this. I extracted the state logic to a new component ToggleView

function ToggleView({name, value}) {
  const [collapsed, setCollapsed] = useState(true);

  return (
    <TouchableOpacity onPress={() => setCollapsed(!collapsed)}>
      <View style={styles.list}>
        <Text style={styles.accName}>{name}</Text>
        <Text style={styles.accValue}>{value}</Text>
      </View>
    </TouchableOpacity>
  );
}

export default function AppCollapsible({ data }: { data: any }) {
  return (
    <View style={styles.listContainer}>
      {
        data.map((item) => {
          return (
            <ToggleView 
              key={item.id}
              name={item.name}
              value={item.value}
            />
          )
        })
      }
    </View>
  );
}

0
laurenyz On

I had a similar problem - I can think of 2 options.

  1. You can break them out into separate components so that they have separate collapsed values.
  2. You could give them ids and set the active id with useState instead. If you want only one to be opened at a time, you could set the default value to "". `const [collapsedId, setCollapsedId] = useState(""); If you wanted to be able to have multiple, you could set the default as an array and then add or remove items by their id onClick.