SectionList: React Native의 섹션 구조와 API란

저자: IT Sectr 게시일: 2026-07-05 읽는 시간: 10 분

SectionList는 요소를 카테고리별로 그룹화하여 섹션화된 리스트를 표시하는 React Native 컴포넌트입니다. FlatList와 달리 SectionList는 헤더와 데이터가 있는 섹션 배열을 받아 알파벳 색인, 카탈로그 및 메뉴를 만들 수 있습니다. 이 컴포넌트는 스크롤 시 고정되는 sticky headers를 지원합니다. 리스트 API에 대한 자세한 내용은 Meta 공식 가이드를 참조하세요.

핵심 내용

  • SectionList는 VirtualizedList 위에 구축된, 헤더가 있는 섹션으로 요소를 그룹화하는 컴포넌트입니다
  • 데이터 구조는 섹션 배열로 구성되며, 각 섹션은 title과 data 배열을 포함합니다
  • Sticky headers는 스크롤 시 섹션 헤더를 화면 상단에 고정합니다
  • 성능은 FlatList의 가상화 메커니즘(윈도우 렌더링 및 셀 재사용)을 상속합니다
  • SectionSeparatorComponent를 사용하면 요소 구분선과 독립적으로 섹션 간 구분선을 사용자 정의할 수 있습니다

SectionList란?

SectionList는 논리적 섹션으로 그룹화된 데이터를 표시하는 React Native 컴포넌트입니다. 각 섹션에는 헤더와 항목 리스트가 있으며, 알파벳 순서의 연락처, 카테고리별 메뉴, 날짜별 주문에 이상적입니다. 이 컴포넌트는 VirtualizedList 위에 구축되어 가상화의 모든 이점을 상속받습니다.

SectionList는 React Native 0.43에서 FlatList와 함께 도입되었으며, 이후 분류된 리스트의 표준이 되었습니다. Meta(2026년)에 따르면 React Native 프로젝트의 40%가 구조화된 데이터를 구성하기 위해 SectionList를 사용합니다. FlatList 내부의 수동 그룹화와 달리 SectionList는 내장된 섹션 지원을 제공합니다.

주요 사용 사례

SectionList는 각 문자가 별도의 섹션인 알파벳 색인이 있는 연락처 리스트에서 사용됩니다. 전자상거래에서는 컴포넌트가 제품을 카테고리나 브랜드별로 그룹화합니다. 메모 앱에서는 날짜나 태그별로, 설정 화면에서는 섹션별(일반, 보안, 알림)로 사용됩니다.

React Native 사용 연구(Meta, 2026년)에 따르면 SectionList는 각각 3-20개의 항목이 있는 5-50개의 섹션에서 가장 효과적입니다. 섹션이 적을 경우 ListHeaderComponent를 통한 그룹화와 함께 FlatList를 사용하는 것이 더 간단합니다. 섹션이 많을 경우 헤더 수가 많아 성능 문제가 발생합니다.

데이터 구조와 섹션

SectionList Data는 Section 객체의 배열을 받으며, 각 객체에는 title(섹션 헤더)과 data(항목 배열)가 포함됩니다. 선택적으로 각 섹션에 대해 별도로 key와 renderItem을 전달하여 공통 renderItem을 재정의할 수 있습니다.

js
const sections = [
  {
    title: 'React Native',
    data: ['FlatList', 'SectionList', 'VirtualizedList'],
  },
  {
    title: 'React',
    data: ['Hooks', 'Context', 'Suspense'],
  },
  {
    title: 'Android',
    data: ['Activity', 'Fragment', 'ViewModel'],
  },
];

renderSectionHeader는 섹션 객체를 받아 섹션 헤더를 렌더링하는 함수입니다. renderItem은 FlatList와 유사한 항목 렌더링 함수입니다. 컴포넌트는 각 섹션의 하단에 renderSectionFooter도 지원합니다.

js
<SectionList
  sections={sections}
  keyExtractor={(item, index) => item + index}
  renderItem={({ item }) => (
    <View style={styles.item}>
      <Text>{item}</Text>
    </View>
  )}
  renderSectionHeader={({ section }) => (
    <View style={styles.sectionHeader}>
      <Text style={styles.sectionTitle}>{section.title}</Text>
    </View>
  )}
/>

Sticky headers와 섹션 네비게이션

Sticky headers는 SectionList의 핵심 기능입니다. 사용자가 스크롤하면 현재 섹션의 헤더가 섹션이 완전히 스크롤될 때까지 화면 상단에 고정됩니다. 이를 통해 사용자는 현재 카테고리에 대한 지속적인 컨텍스트를 얻을 수 있습니다.

스티키 모드는 기본적으로 활성화되어 있습니다. 비활성화하려면 stickySectionHeadersEnabled={false}를 사용하세요. iOS에서는 헤더가 네이티브 애니메이션으로 고정되고, Android에서는 JS 처리를 통해 고정됩니다. 알파벳 참조의 경우 빠른 탐색을 위해 문자가 있는 사이드바를 추가하는 것이 편리합니다.

js
const ContactsList = () => {
  const sectionListRef = React.useRef(null);

  const scrollToSection = (index) => {
    sectionListRef.current?.scrollToLocation({
      sectionIndex: index,
      itemIndex: 0,
      viewPosition: 0,
    });
  };

  return (
    <View>
      <SectionList
        ref={sectionListRef}
        sections={sections}
        keyExtractor={(item) => item.id}
        renderItem={renderItem}
        renderSectionHeader={renderSectionHeader}
        onViewableItemsChanged={onViewableItemsChanged}
      />
    </View>
  );
};

scrollToLocation은 프로그래밍 방식으로 섹션으로 이동하는 메서드입니다. sectionIndex, itemIndex 및 viewPosition(0 — 시작, 0.5 — 중간, 1 — 끝)을 받습니다. 사이드바 알파벳 색인과 결합하면 표준 iOS 연락처와 같은 빠른 탐색을 구현할 수 있습니다.

SectionList 성능 최적화

SectionList 최적화는 FlatList 최적화와 동일한 원칙을 따르지만 섹션과 관련된 추가적인 고려사항이 있습니다. 각 섹션 헤더는 스크롤 중에 렌더링 및 재렌더링되는 추가 View입니다. 50개 이상의 섹션이 있는 경우 헤더로 인해 스크롤이 느려질 수 있습니다.

불필요한 재렌더링을 방지하기 위해 renderSectionHeader 및 renderItem에 React.memo를 사용하세요. 섹션이 동적으로 변경되지 않는 경우 섹션 배열에 useMemo를 고려하세요. 매우 큰 리스트의 경우 헤더와 항목의 고정 높이를 지정하여 SectionList를 getItemLayout과 결합하세요.

최적화 기법설명효과
React.memo헤더 및 항목 컴포넌트 메모이제이션스크롤 시 재렌더링 횟수 감소
getItemLayout헤더 + 항목의 고정 높이측정 제거, 인덱스로 스크롤 가속화
maxToRenderPerBatch배치당 항목 수 제한빠른 스크롤 시 지연 방지
windowSize대규모 리스트의 경우 5-10으로 감소동시 렌더링 항목 수 감소

SectionList vs FlatList: 언제 무엇을 선택할까

SectionList와 FlatList 사이의 선택은 데이터 구조에 따라 달라집니다. 데이터가 평면 배열인 경우 FlatList를 사용하세요. 데이터가 자연스럽게 헤더가 있는 카테고리로 그룹화되는 경우 SectionList를 사용하세요. 단일 섹션에 SectionList를 사용하지 마세요. FlatList가 더 효율적으로 처리합니다.

동일한 항목 수에서 성능 차이는 미미합니다. SectionList는 헤더 렌더링에 오버헤드를 추가하지만, 헤더가 의미를 가질 때 이 오버헤드는 정당화됩니다. 헤더가 필요하지 않은 경우 섹션 시뮬레이션을 위해 ListHeaderComponent와 함께 FlatList를 사용하는 것이 더 빠릅니다.

선택 기준

SectionList를 사용하는 경우: 데이터가 기본적으로 그룹화된 경우(문자별 연락처), sticky headers가 필요한 경우, 섹션 헤더에 대화형 요소(버튼, 체크박스)가 포함된 경우. FlatList를 사용하는 경우: 데이터가 평면인 경우, 그룹화가 동적으로 변경되는 경우, 50개 이상의 카테고리가 있고 헤더가 균일한 경우.

SectionList 구현 예제

SectionList와 알파벳 색인의 조합은 고전적인 사용 사례입니다. 구현에는 문자가 있는 사이드바와 섹션으로 이동하기 위한 scrollToLocation이 포함됩니다. 아래는 알파벳 탐색이 있는 연락처 리스트의 전체 구현입니다.

js
const ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');

const AlphabetContacts = () => {
  const ref = React.useRef(null);

  const sections = React.useMemo(() =>
    ALPHABET.map(letter => ({
      title: letter,
      data: contacts.filter(c => c.name.startsWith(letter)),
    })).filter(s => s.data.length > 0),
  []);

  return (
    <View style={styles.container}>
      <SectionList
        ref={ref}
        sections={sections}
        keyExtractor={item => item.id}
        renderItem={renderContact}
        renderSectionHeader={renderHeader}
        getItemLayout={getItemLayout}
      />
      <View style={styles.sidebar}>
        {ALPHABET.map(letter => (
          <Text
            key={letter}
            onPress={() => scrollToSection(letter)}
          >{letter}</Text>
        ))}
      </View>
    </View>
  );
};

중요: 섹션을 동적으로 필터링할 때는 useMemo를 사용하여 배열을 안정화하세요. 메모이제이션이 없으면 SectionList는 필터가 변경될 때마다 모든 셀을 다시 생성하여 스크롤 위치와 중첩된 컴포넌트의 상태가 손실됩니다.

자주 묻는 질문

SectionList를 동적 섹션과 함께 사용할 수 있나요?

네, SectionList는 동적 섹션 변경을 지원합니다. 섹션 배열이 변경되면 컴포넌트는 변경된 섹션만 다시 렌더링합니다. 안정적인 작동을 위해 각 섹션에 key를 사용하고 컴포넌트를 React.memo로 감싸세요.

SectionList에서 빈 섹션을 숨기는 방법은?

전달하기 전에 섹션 배열을 필터링하세요: 빈 data가 있는 섹션을 제거하세요. 데이터가 API에서 오는 경우 useMemo에서 필터링을 처리하세요. 전체 리스트의 빈 상태에는 ListEmptyComponent를 사용하세요.

Android에서 sticky headers가 작동하지 않는 이유는?

Android에서 Sticky headers는 기본적으로 활성화되어 있지만 nestedScrollEnabled와 충돌할 경우 작동하지 않을 수 있습니다. SectionList가 ScrollView 내부에 중첩되지 않았는지 확인하세요. Android 12+에서는 스티키 헤더가 네이티브 메커니즘을 통해 작동하고, 이전 버전에서는 JS를 통해 작동합니다.

스티키 헤더 전환 애니메이션을 사용자 정의하는 방법은?

SectionList는 내장된 스티키 헤더 전환 애니메이션을 제공하지 않습니다. 사용자 정의 애니메이션의 경우 onViewableItemsChanged를 추적하고 Animated API 또는 react-native-reanimated를 사용하여 헤더 변경을 애니메이션화하세요.

추가 섹션이 SectionList 성능에 영향을 미치나요?

네, 각 섹션은 DOM에 헤더를 추가합니다. 100개 이상의 섹션이 있는 경우 헤더 수가 많아 SectionList 성능이 저하됩니다. 해결책: 데이터를 10-20개의 논리적 섹션으로 그룹화하거나 사용자 정의 그룹화와 함께 FlatList를 사용하세요.

요약

  • SectionList는 헤더와 sticky headers가 있는 섹션으로 그룹화된 데이터를 표시하는 React Native 컴포넌트입니다
  • 섹션 구조는 title(헤더)과 data(항목 배열)로 구성되며, sections prop을 통해 전달됩니다
  • Sticky headers는 스크롤 중 현재 섹션 헤더를 고정하여 긴 리스트에서 탐색을 개선합니다
  • 최적화를 위해 헤더에 React.memo, 섹션에 useMemo, 고정 높이에 getItemLayout이 필요합니다
  • scrollToLocation은 인덱스로 모든 섹션에 프로그래밍 방식 탐색을 제공합니다
  • SectionList vs FlatList: SectionList는 헤더가 있는 분류 데이터용, FlatList는 평면 배열용
  • 알파벳 색인은 scrollToLocation을 통해 SectionList와 결합하여 문자 기반 빠른 탐색을 제공합니다

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기