Home > Software design >  How to conditionally render these items in a React-Native Flatlist
How to conditionally render these items in a React-Native Flatlist

Time:01-10

I'm getting a json object that looks like this:

Array [
  Object {
    "department": "department 1",
    "formName": "form 1",
    "id": 1,
  },
  Object {
    "department": "department 1",
    "formName": "form 2",
    "id": 2,
  },
  Object {
    "department": "deparment 1",
    "formName": "form 3",
    "id": 3,
  },
  Object {
    "department": "department 1",
    "formName": "form 4",
    "id": 4,
  },
  Object {
    "department": "department 2",
    "formName": "form 5",
    "id": 5,
  },

]

as you can see, there are only 2 unique departments, but 5 different forms. 4 of the forms belong to department 1 and the other remaining form belongs to department 2

I am trying to render 2 buttons that look something like this:

department 1

  • form 1
  • form 2
  • form 3
  • form 4

department 2

  • form 5

this is the flat list component I have at the moment

    <FlatList
      data={this.state.dataList}
      keyExtractor={(item) => item.id.toString()}
      renderItem={({ item }) => {
        return (
          <TouchableWithoutFeedback
            onPress={console.log("touched")}
            style={styles.clearBtn}
          >
            <Text style={styles.clearBtnText}>{item.department}</Text>
            <Text style={styles.clearBtnText2}>{item.formName}</Text>
          </TouchableWithoutFeedback>
        );
      }}
    />

However, this obviously renders 5 buttons that look like this:

department 1

  • form 1

department 1

  • form 2

department 1

  • form 3

department 1

  • form 4

department 2

  • form 5

CodePudding user response:

You may want to remodel your data and use a SectionList instead of a FlatList, it looks more fitting for your use case.

The official docs are here, and if we go by their example your data should look something like:

[
   {
     title: 'Department 1',
     data: [{formName: 'form1', id: 1} ,{formName: 'form2', id:2} ...]
   },
   {
     title: 'Department 2',
     data: [{formName: 'form5', id: 5}]
   }  
]

And your SectionList render would look like

<SectionList
      sections={this.state.dataList}
      keyExtractor={(item) => item.id.toString()}
      renderSectionHeader={({ section: { title } }) => (
        <Text style={/*Whatever style you want*/}>{title}</Text>
      )}
      renderItem={({ item }) => {
        return (
          <TouchableWithoutFeedback
            onPress={() => console.log("touched")}
            style={styles.clearBtn}
          >
            <Text style={styles.clearBtnText2}>{item.formName}</Text>
          </TouchableWithoutFeedback>
        );
      }}
    />

Assuming this.state.dataList is the data model I have presented

CodePudding user response:

as @Ron B. suggested, you need to convert your data from flat to section array structure as below.

const flatToSection = (data)=>{
  const getDepartmentData = (department,data)=>{
return data.filter(item=> item.department === department)
}
const departments =[...new Set( data.map(el=> el.department))]

const sections = departments.map((department)=>({
 title:department,
 data :getDepartmentData(department,data)

}))

return sections

}

export default flatToSection


Then replace FlatList with Section list.

Working example - https://snack.expo.dev/@emmbyiringiro/c8a7cd

  •  Tags:  
  • Related