SectionList

SectionList virtualizes grouped data. Instead of data it takes sections, an array of objects that each have a data array plus whatever else you need, usually a title. renderSectionHeader and renderSectionFooter draw the group boundaries, and a section may override renderItem, keyExtractor or ItemSeparatorComponent for its own rows. BookNest groups its catalog by genre:

src/Genres.tsx: the catalog grouped by genre (excerpt)TSX
export function byGenre(books: Book[]) {
  const groups = new Map<string, Book[]>();
  for (const b of books) groups.set(b.genre, [...(groups.get(b.genre) ?? []), b]);
  return [...groups].map(([title, data]) => ({ title, data }))
    .sort((a, b) => a.title.localeCompare(b.title));
}
// ...
    <SectionList sections={sections} keyExtractor={(b) => String(b.id)}
      renderItem={({ item }) => <BookRow book={item} />}
      renderSectionHeader={({ section }) => <Header title={section.title} />}
      renderSectionFooter={({ section }) => (
        <Text style={g.footer}>{section.data.length} books in {section.title}</Text>
      )}

byGenre is plain TypeScript with no React Native 36,878 imports, so it can be unit-tested without an emulator (Testing React Native Apps). To jump to a group, scrollToLocation({ sectionIndex, itemIndex }) plays the part of scrollToIndex.