Search code examples
react-nativereact-native-sectionlistreact-native-collapsible

Section list with collapsible section header in react-native


I am using react-native version 0.61.5. I want to do a section list with a collapsible header in react-native as shown in the below image.

Here is my API data formate

data:[
  {
    shift_name:'Day',
    data:[
    {
      id:'1',
      fullname: "seela",
      inspection_date: "2020-06-10T04:45:32Z",
      issues: 1,
      response:{
        shift_name:'Day'
      }
     }
    ]
  },
  {
    shift_name:'Afternoon',
    data:[
      {
        id:'2',
        fullname: "Raju vijayan",
        inspection_date: "2020-06-9T04:45:32Z",
        issues: 3,
        response:{
          shift_name:'Afternoon'
        }
      },
      {
        id:'3',
        fullname: "Pratap P",
        inspection_date: "2020-06-8T04:45:32Z",
        issues: 2,
        response:{
          shift_name:'Afternoon'
        }
      }
    ]
  }
]

enter image description here

When I click on header content should expand and collapse. How can I do it in react-native?


Solution

  • Make each item a component.

    Use Layoutanimation for your requirement.

    Use a state to manage the states of item. ie, open and close.

    const [open, setopen] = useState(false);
    

    Initially, the item is in a close state.

    Display data according to the condition.

    Logic: you only need to specify the height only if the item is closed.

    !open && { height: 40 }
    

    if it's not open, give the header height. Otherwise, it will occupy the height it needs.

    Full code

    import React, { useState } from 'react';
    import {
      View, Text, StyleSheet, TouchableOpacity, LayoutAnimation, Platform, UIManager,
    } from 'react-native';
    
    if (Platform.OS === 'android') {
      if (UIManager.setLayoutAnimationEnabledExperimental) {
        UIManager.setLayoutAnimationEnabledExperimental(true);
      }
    }
    
    
    export default function TestFile() {
      return (
        <View style={styles.container}>
          <Item />
          <Item />
          <Item />
          <Item />
          <Item />
          <Item />
        </View>
      );
    }
    
    
    function Item() {
      const [open, setopen] = useState(false);
      const onPress = () => {
        LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
        setopen(!open);
      };
      return (
        <TouchableOpacity style={[styles.item, !open && { height: 40 }]} onPress={onPress} activeOpacity={1}>
          <Text>Header</Text>
          {open && (
            <View>
              <Text> SOME DATA</Text>
              <Text> SOME DATA</Text>
              <Text> SOME DATA</Text>
              <Text> SOME DATA</Text>
              <Text> SOME DATA</Text>
              <Text> SOME DATA</Text>
            </View>
          )}
        </TouchableOpacity>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        alignItems: 'center',
        padding: 50,
      },
      item: {
        width: '100%',
        borderWidth: 1,
        paddingHorizontal: 20,
        overflow: 'hidden',
        paddingVertical: 10,
        marginBottom: 5,
      },
    });
    
    

    Result

    enter image description here