21

See https://facebook.github.io/react-native/docs/sectionlist.html

When one of the Section's is empty (e.a. the data prop is an empty array), I would still like to render the SectionHeader, but also render a component that indicates that the section contains no data.

I know for the FlatList component this is possible using the ListEmptyComponent prop, but how does this work for the SectionList component?

I was hoping for something like this (but it doesn't work):

<SectionList
    style={styles.container}
    renderSectionHeader={({section}) => <SectionHeader title={section.title} />}
    sections={[
      {
        data: Object.values(this.props.teams),
        title: 'Teams',
        renderItem: this._renderTeamItem,
        keyExtractor: item => item.id,
        ListEmptyComponent: this._renderEmpty
      },
      {
        data: Object.values(this.props.invites),
        title: 'Invites',
        renderItem: this._renderInviteItem,
        keyExtractor: item => item.id,
        ListEmptyComponent: this._renderEmpty
      }
    ]}
  />
Michiel
  • 956
  • 2
  • 7
  • 19

5 Answers5

56

You could use the renderSectionFooter to display any 'no content' component. Check out the following little example:

<SectionList
   renderSectionFooter={this.renderNoContent}
   section={[
      {data: ['1', '2']},
      {data: []}
   ]}
/>

renderNoContent = ({section}) => {
   if(section.data.length == 0){
      return NO_CONTENT_COMPONENT
   }
   return null
}
Arbnor
  • 2,190
  • 18
  • 26
  • 4
    Could be a nice feature to have. Something like `renderEmptySectionComponent`. – Laura Aug 22 '18 at 13:25
  • 4
    You can change `renderSectionFooter={({section}) => this.renderNoContent(section)}` to `renderSectionFooter={this.renderNoContent}` to avoid extra renders. – Jojo Narte Nov 24 '19 at 04:53
  • Can data in section be a component instead of an array? – ChuChu Jun 18 '20 at 04:10
8

I'm little late for the party, but since I just had to do this and I wasted a little more time on it than I'm comfortable admitting, I'll try to wrap everything up.

You can't use SectionList's ListEmptyComponent to achieve this as you do with the FlatList component. ListEmptyComponentis only triggered when the data prop is empty. If however you have any section in the data prop, then ListEmptyComponent won't be triggered.

One of the replies suggests using renderItem and checking inside of it whether section.data.length equals 0. That's nice idea, except that renderItem won't be called for sections that have data.length === 0. So this approach won't work.

What you are left with is either using renderSectionHeaderor renderSectionFooter - which one you decide to use is up to you and your specific use case.

The renderSection*function receives the section and there you are able to check whether the section has a data prop with length > 0. If it doesn't this would be your chance to output an EmptyComponent.

With the specific example in the question it would look something like this:

<SectionList
    style={styles.container}
    renderSectionHeader={({section}) => {
      if (section.data.length === 0) {
        return section.ListEmptyComponent     
      }
      return <SectionHeader title={section.title} />

    }
    sections={[
      {
        data: Object.values(this.props.teams),
        title: 'Teams',
        renderItem: this._renderTeamItem,
        keyExtractor: item => item.id,
        ListEmptyComponent: this._renderEmpty
      },
      {
        data: Object.values(this.props.invites),
        title: 'Invites',
        renderItem: this._renderInviteItem,
        keyExtractor: item => item.id,
        ListEmptyComponent: this._renderEmpty
      }
    ]}
  />
Daniel Dimitrov
  • 1,848
  • 21
  • 35
1
<SectionList
    style={styles.container}
    renderSectionHeader={({section}) => <SectionHeader title={section.title} />}
    sections={[
      {
        data: Object.values(this.props.teams),
        title: 'Teams',
        renderItem: this._renderTeamItem,
        keyExtractor: item => item.id,
        ListEmptyComponent: this._renderEmpty
      },
      {
        data: Object.values(this.props.invites),
        title: 'Invites',
        renderItem: this._renderInviteItem,
        keyExtractor: item => item.id,
        ListEmptyComponent: this._renderEmpty
      }
    ].filter(s => s.data.length > 0)}
  />

try to filter out empty sections :)

aesde
  • 11
  • 1
0

Easy way. And you will get all the Components except the Component that renders the data.

const myData = items?.length ? DATA : [] 

<SectionList
        sections={myData}
        keyExtractor={getKeyExtractor}
        renderItem={renderItem}
        renderSectionHeader={renderSectionHeader}
        ListHeaderComponent={renderHeader}
        ListFooterComponent={renderFooterComponent}
      />
-2

Should work in the exact same way I believe: listEmptyComponent

Alternatively you could also do a conditional in your JSX to render the message for there being no data

Shayan Javadi
  • 293
  • 3
  • 20
  • 6
    The ListEmptyComponent gets rendered when the list of sections provided is empty, not when one of the sections is empty. A conditional might work, but that code would soon become bulky. I was hoping that there was a way to do it just like the listEmptyComponent, but for empty sections instead. Like passing in a ListEmptyComponent for each of the sections – Michiel Sep 29 '17 at 07:25