SectionList: cấu trúc phần và API trong React Native là gì

Tác giả: IT Sectr Đã đăng: 2026-07-05 Thời gian đọc: 10 phút

SectionList là thành phần React Native để hiển thị danh sách được phân vùng với các phần tử được nhóm theo danh mục. Không giống như FlatList, SectionList chấp nhận một mảng các phần với tiêu đề và dữ liệu, cho phép tạo chỉ mục chữ cái, danh mục và menu. Thành phần hỗ trợ sticky headers — tiêu đề cố định khi cuộn. Tìm hiểu thêm về API danh sách trong hướng dẫn chính thức của Meta.

Những điểm chính

  • SectionList là thành phần để nhóm các phần tử vào các phần có tiêu đề, được xây dựng trên VirtualizedList
  • Cấu trúc dữ liệu bao gồm một mảng các phần, mỗi phần chứa title và mảng data
  • Sticky headers cố định tiêu đề phần ở đầu màn hình khi cuộn
  • Hiệu suất kế thừa cơ chế ảo hóa của FlatList — hiển thị theo cửa sổ và tái sử dụng ô
  • SectionSeparatorComponent cho phép tùy chỉnh dấu phân cách giữa các phần độc lập với dấu phân cách phần tử

SectionList là gì?

SectionList là thành phần React Native để hiển thị dữ liệu được nhóm thành các phần logic. Mỗi phần có một tiêu đề và một danh sách các mục, lý tưởng cho danh bạ theo thứ tự chữ cái, menu theo danh mục, đơn hàng theo ngày. Thành phần được xây dựng trên VirtualizedList và kế thừa tất cả lợi ích của ảo hóa.

SectionList được giới thiệu cùng với FlatList trong React Native 0.43 và từ đó trở thành tiêu chuẩn cho danh sách phân loại. Theo Meta (2026), 40% dự án React Native sử dụng SectionList để tổ chức dữ liệu có cấu trúc. Không giống như nhóm thủ công bên trong FlatList, SectionList cung cấp hỗ trợ phần tích hợp sẵn.

Các trường hợp sử dụng chính

SectionList được sử dụng trong danh sách liên lạc với chỉ mục chữ cái, nơi mỗi chữ cái là một phần riêng biệt. Trong thương mại điện tử, thành phần nhóm sản phẩm theo danh mục hoặc thương hiệu. Trong ứng dụng ghi chú — theo ngày hoặc thẻ. Trong màn hình cài đặt — theo phần (Chung, Bảo mật, Thông báo).

Theo nghiên cứu sử dụng React Native (Meta, 2026), SectionList hiệu quả nhất với 5-50 phần, mỗi phần chứa 3-20 mục. Với ít phần hơn, việc sử dụng FlatList với nhóm qua ListHeaderComponent sẽ đơn giản hơn. Với nhiều phần hơn, các vấn đề về hiệu suất phát sinh do số lượng tiêu đề lớn.

Cấu trúc dữ liệu và các phần

SectionList Data chấp nhận một mảng các đối tượng Section, mỗi đối tượng chứa title (tiêu đề phần) và data (mảng các mục). Tùy chọn, có thể truyền key và renderItem riêng cho từng phần, ghi đè renderItem chung.

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

renderSectionHeader là hàm hiển thị tiêu đề phần, nhận đối tượng phần. renderItem là hàm hiển thị mục, tương tự FlatList. Thành phần cũng hỗ trợ renderSectionFooter cho phần dưới cùng của mỗi phần.

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 và điều hướng theo phần

Sticky headers là tính năng chính của SectionList. Khi người dùng cuộn, tiêu đề của phần hiện tại sẽ dính vào đầu màn hình cho đến khi phần được cuộn qua hoàn toàn. Điều này cung cấp cho người dùng ngữ cảnh liên tục về danh mục hiện tại.

Chế độ dính được bật theo mặc định. Để tắt, sử dụng stickySectionHeadersEnabled={false}. Trên iOS, tiêu đề dính với hoạt ảnh gốc; trên Android, thông qua xử lý JS. Đối với danh bạ chữ cái, rất tiện lợi khi thêm thanh bên với các chữ cái để điều hướng nhanh.

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 là phương pháp điều hướng lập trình đến bất kỳ phần nào. Nó chấp nhận sectionIndex, itemIndex và viewPosition (0 — đầu, 0.5 — giữa, 1 — cuối). Kết hợp với chỉ mục chữ cái bên cạnh, bạn có thể triển khai điều hướng nhanh như trong danh bạ iOS tiêu chuẩn.

Tối ưu hóa hiệu suất SectionList

Tối ưu hóa SectionList tuân theo các nguyên tắc tương tự như tối ưu hóa FlatList, với các sắc thái bổ sung liên quan đến các phần. Mỗi tiêu đề phần là một View bổ sung được hiển thị và hiển thị lại khi cuộn. Với 50+ phần, các tiêu đề có thể làm chậm cuộn.

Sử dụng React.memo cho renderSectionHeader và renderItem để tránh hiển thị lại không cần thiết. Nếu các phần không thay đổi động, hãy cân nhắc useMemo cho mảng các phần. Đối với danh sách rất lớn, kết hợp SectionList với getItemLayout, chỉ định chiều cao cố định cho tiêu đề và mục.

Kỹ thuật tối ưu hóaMô tảHiệu quả
React.memoGhi nhớ thành phần tiêu đề và mụcGiảm số lần hiển thị lại khi cuộn
getItemLayoutChiều cao cố định của tiêu đề + mụcLoại bỏ đo lường, tăng tốc cuộn đến chỉ mục
maxToRenderPerBatchGiới hạn mục mỗi đợtNgăn chặn độ trễ khi cuộn nhanh
windowSizeGiảm xuống 5-10 cho danh sách lớnGiảm số lượng mục được hiển thị đồng thời

SectionList vs FlatList: khi nào chọn cái gì

Lựa chọn giữa SectionList và FlatList phụ thuộc vào cấu trúc dữ liệu. Nếu dữ liệu là mảng phẳng — hãy sử dụng FlatList. Nếu dữ liệu tự nhiên nhóm thành các danh mục có tiêu đề — hãy sử dụng SectionList. Không sử dụng SectionList cho một phần duy nhất — FlatList sẽ xử lý hiệu quả hơn.

Sự khác biệt về hiệu suất là tối thiểu với cùng số lượng mục. SectionList thêm chi phí cho việc hiển thị tiêu đề, nhưng chi phí này là hợp lý khi tiêu đề mang ý nghĩa. Nếu không cần tiêu đề — FlatList với ListHeaderComponent để mô phỏng các phần sẽ nhanh hơn.

Tiêu chí lựa chọn

Sử dụng SectionList khi: dữ liệu được nhóm theo mặc định (danh bạ theo chữ cái), cần sticky headers, tiêu đề phần chứa các phần tử tương tác (nút, hộp kiểm). Sử dụng FlatList khi: dữ liệu phẳng, nhóm thay đổi động, có hơn 50 danh mục và tiêu đề đồng nhất.

Ví dụ triển khai SectionList

SectionList với chỉ mục chữ cái là trường hợp sử dụng cổ điển. Việc triển khai bao gồm thanh bên với các chữ cái và scrollToLocation để nhảy đến một phần. Dưới đây là triển khai đầy đủ của danh sách liên lạc với điều hướng chữ cái.

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>
  );
};

Quan trọng: khi lọc các phần động, hãy sử dụng useMemo để ổn định mảng. Nếu không ghi nhớ, SectionList sẽ tạo lại tất cả các ô mỗi khi bộ lọc thay đổi, dẫn đến mất vị trí cuộn và trạng thái của các thành phần lồng nhau.

Câu hỏi thường gặp

Có thể sử dụng SectionList với các phần động không?

Có, SectionList hỗ trợ thay đổi phần động. Khi mảng các phần thay đổi, thành phần chỉ hiển thị lại các phần đã thay đổi. Để hoạt động ổn định, hãy sử dụng key cho mỗi phần và bọc các thành phần trong React.memo.

Làm thế nào để ẩn các phần trống trong SectionList?

Lọc mảng các phần trước khi truyền: loại bỏ các phần có data trống. Nếu dữ liệu đến từ API, xử lý lọc trong useMemo. Đối với trạng thái trống của toàn bộ danh sách, hãy sử dụng ListEmptyComponent.

Tại sao sticky headers không hoạt động trên Android?

Sticky headers trên Android được bật theo mặc định, nhưng có thể không hoạt động khi xung đột với nestedScrollEnabled. Đảm bảo SectionList không được lồng bên trong ScrollView. Trên Android 12+, sticky headers hoạt động thông qua cơ chế gốc; trên các phiên bản cũ hơn, thông qua JS.

Làm thế nào để tùy chỉnh hoạt ảnh chuyển đổi sticky header?

SectionList không cung cấp hoạt ảnh chuyển đổi sticky header tích hợp sẵn. Để có hoạt ảnh tùy chỉnh, theo dõi onViewableItemsChanged và tạo hoạt ảnh thay đổi tiêu đề bằng Animated API hoặc react-native-reanimated.

Các phần bổ sung có ảnh hưởng đến hiệu suất của SectionList không?

Có, mỗi phần thêm một tiêu đề vào DOM. Với 100+ phần, hiệu suất của SectionList giảm do số lượng tiêu đề lớn. Giải pháp: nhóm dữ liệu thành 10-20 phần logic hoặc sử dụng FlatList với nhóm tùy chỉnh.

Tóm tắt

  • SectionList là thành phần React Native để hiển thị dữ liệu được nhóm thành các phần có tiêu đề và sticky headers
  • Cấu trúc phần bao gồm title (tiêu đề) và data (mảng các mục), được truyền qua prop sections
  • Sticky headers cố định tiêu đề phần hiện tại khi cuộn, cải thiện điều hướng trong danh sách dài
  • Tối ưu hóa yêu cầu React.memo cho tiêu đề, useMemo cho phần và getItemLayout cho chiều cao cố định
  • scrollToLocation cung cấp điều hướng lập trình đến bất kỳ phần nào theo chỉ mục
  • SectionList vs FlatList: SectionList cho dữ liệu phân loại có tiêu đề, FlatList cho mảng phẳng
  • Chỉ mục chữ cái kết hợp với SectionList qua scrollToLocation để điều hướng nhanh theo chữ cái

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm