Search code examples
reactjsreact-nativerenderreact-native-sectionlist

Render different components for each section of React Native SectionList


I am building a section list. Each section has a different data object with varying values. Because of that I need to render a different component for each section but am having a hard time figuring out how to do so.

Here is my DATA array (two are dummies for now)

const DATA = [
{
  title: "Groups",
  data: [
    {
      groupName: "Samwise",
    },
    
  ],
},
{
  title: "Noters"
    {
      userName: "Merri",
    },
  ],
},
{
  title: "Contacts",
  data: termIsContact.length ? termIsContact : contacts,
}]

SectionList component

<SectionList
  sections={DATA}
  keyExtractor={(item, index) => item + index}
  renderItem={renderItem}
  renderSectionHeader={({ section: { title } }) => (
    <View style={tw.style(`justify-center bg-red-100 pl-4`, { height: 28 })}>
      <Text style={tw`text-base font-bold`}>{title}</Text>
    </View>
  )}
/>

How I am rendering the Contacts list

const Item = ({ givenName, familyName }) => (
  <TouchableOpacity
    onPress={() => toggleContact(`${givenName} ${familyName}`)}
    style={tw.style("justify-start pl-4 w-full flex flex-row items-center", {
      height: 56,
      borderBottomColor: "#aaaaaa",
      borderBottomWidth: 1,
    })}
  >
    <Avatar
      name={`${givenName} ${familyName}`}
      size={32}
      backgroundColor={"#D9F3FC"}
      labelColor={"#16ade0"}
    />

    <Text style={tw.style("text-black text-base pl-2", {})}>
      {givenName} {familyName}
    </Text>
  </TouchableOpacity>
)

const renderItem = ({ item }) => <Item familyName={item.familyName} givenName={item.givenName} />

My thinking is to create an <Item /> to be rendered for each of the sections but just cant figure out how to get each section to render its own style from the data in that sections data object.

Thank you very much in advance


Solution

  • I found the solution and hope this is helpful to someone in the future looking for the same.

    The sections array allows each object in it to take in a prop renderItem so you can create a unique component for each section.

    My Component

    const NotersItem = ({ userName }) =>
    searchTerm && !termIsUser.length ? (
      <></>
    ) : (
      <TouchableOpacity
        onPress={() => toggleContact(`${userName}`)}
        style={tw.style("justify-start pl-4 w-full flex flex-row items-center", {
          height: 48,
          borderBottomColor: "#aaaaaa",
          borderBottomWidth: 1,
        })}
      >
        <Avatar name={`${userName}`} size={32} backgroundColor={"#D9F3FC"} labelColor={"#16ade0"} />
    
        <Text style={tw.style("text-black text-base pl-2", {})}>{userName}</Text>
      </TouchableOpacity>
    )
    
      const renderNotersItem = ({ item }) => <NotersItem userName={item.userName} />
    

    Section Array

      const DATA = [
    {
      title: "Groups",
      renderItem: renderGroupItem,
      data: termIsGroup.length ? termIsGroup : groups,
    },
    {
      title: "Highnoters",
      renderItem: renderNotersItem,
      data: termIsUser.length ? termIsUser : users,
    },
    {
      title: "Contacts",
      renderItem: renderContactItem,
      data: termIsContact.length ? termIsContact : contacts,
    },
    

    ]

    SectionList component

          sections={DATA}
          keyExtractor={(item, index) => item + index}
          renderItem={({ section: { renderItem } }) => <View>{renderItem}</View>}
          renderSectionHeader={({ section }) => (
            <View style={tw.style(`justify-center bg-red-100 pl-4`, { height: 28 })}>
              <Text style={tw`text-base font-bold`}>{section.title}</Text>
            </View>
          )}
        />
    

    Any questions please comment!