SectionList: ما هو، بنية الأقسام وAPI في React Native

المؤلف: IT Sectr نُشر: 2026-07-05 وقت القراءة: 10 دق

SectionList هو مكون React Native لعرض القوائم المقسمة مع تجميع العناصر حسب الفئات. على عكس FlatList، يقبل SectionList مصفوفة من الأقسام مع عناوين وبيانات، مما يسمح بإنشاء فهارس أبجدية وكتالوجات وقوائم. يدعم المكون sticky headers — العناوين الثابتة أثناء التمرير. اقرأ المزيد عن واجهات برمجة تطبيقات القوائم في الدليل الرسمي من Meta.

الرئيسية

  • SectionList — مكون لتجميع العناصر في أقسام مع عناوين، مبني على VirtualizedList
  • بنية البيانات تتكون من مصفوفة أقسام، كل قسم يحتوي على title ومصفوفة data
  • Sticky headers تثبت عناوين الأقسام في أعلى الشاشة أثناء التمرير
  • الأداء يرث آليات التخيل من FlatList — العرض بنوافذ وإعادة استخدام الخلايا
  • SectionSeparatorComponent يسمح بتخصيص الفواصل بين الأقسام بشكل مستقل عن فواصل العناصر

ما هو SectionList؟

SectionList هو مكون React Native لعرض البيانات المجمعة في أقسام منطقية. كل قسم له عنوان وقائمة عناصر، وهو مثالي لجهات الاتصال حسب الترتيب الأبجدي، والقوائم حسب الفئة، والطلبات حسب التاريخ. المكون مبني على VirtualizedList ويرث جميع مزايا التخيل.

ظهر SectionList مع FlatList في React Native 0.43 ومنذ ذلك الحين أصبح المعيار للقوائم المصنفة. وفقًا لـ Meta (2026)، 40% من مشاريع React Native تستخدم SectionList لتنظيم البيانات المنظمة. على عكس التجميع اليدوي داخل FlatList، يوفر SectionList دعماً مدمجاً للأقسام.

حالات الاستخدام الرئيسية

SectionList يُستخدم في قوائم جهات الاتصال مع فهرس أبجدي، حيث كل حرف هو قسم منفصل. في التجارة الإلكترونية، يقوم المكون بتجميع المنتجات حسب الفئة أو العلامة التجارية. في تطبيقات الملاحظات — حسب التاريخ أو العلامات. في شاشات الإعدادات — حسب الأقسام (عام، الأمان، الإشعارات).

وفقًا لدراسة استخدام React Native (Meta، 2026)، يكون SectionList أكثر فعالية مع 5-50 قسماً تحتوي على 3-20 عنصراً لكل منها. مع عدد أقل من الأقسام، من الأسهل استخدام FlatList مع التجميع عبر ListHeaderComponent. مع عدد أكبر من الأقسام، تنشأ مشاكل في الأداء بسبب العدد الكبير من العناوين.

بنية البيانات والأقسام

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+ قسماً، يمكن للعناوين إبطاء التمرير.

استخدم React.memo لـ renderSectionHeader و renderItem لتجنب إعادة العرض غير الضرورية. إذا لم تتغير الأقسام ديناميكياً، فكر في useMemo لمصفوفة الأقسام. للقوائم الكبيرة جداً، ادمج SectionList مع getItemLayout مع تحديد ارتفاعات ثابتة للعناوين والعناصر.

تقنية التحسينالوصفالتأثير
React.memoحفظ مكونات العناوين والعناصريقلل عدد مرات إعادة العرض أثناء التمرير
getItemLayoutارتفاع ثابت للعنوان + العنصريلغي القياس، يسرع التمرير إلى الفهرس
maxToRenderPerBatchتحديد العناصر في الدفعةيمنع التأخير أثناء التمرير السريع
windowSizeالتقليل إلى 5-10 للقوائم الكبيرةيقلل عدد العناصر المعروضة في وقت واحد

SectionList مقابل FlatList: متى تختار ماذا

الاختيار بين SectionList و FlatList يعتمد على بنية البيانات. إذا كانت البيانات مصفوفة مسطحة — استخدم FlatList. إذا كانت البيانات تتجمع طبيعياً في فئات مع عناوين — استخدم SectionList. لا تستخدم SectionList لقسم واحد — FlatList سيتعامل معه بكفاءة أكبر.

الفرق في الأداء ضئيل عند نفس عدد العناصر. SectionList يضيف حمولة لعرض العناوين، لكن هذه الحمولة مبررة عندما تحمل العناوين معنى. إذا لم تكن العناوين ضرورية — FlatList مع ListHeaderComponent لمحاكاة الأقسام سيكون أسرع.

معايير الاختيار

استخدم 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.

لماذا لا تعمل sticky headers على Android؟

Sticky headers على Android مفعلة افتراضياً، لكنها قد لا تعمل عند التعارض مع nestedScrollEnabled. تأكد من أن SectionList غير متداخل داخل ScrollView. على Android 12+، تعمل sticky headers عبر الآلية الأصلية؛ على الإصدارات القديمة، عبر JS.

كيفية تخصيص حركة انتقال sticky header؟

SectionList لا يوفر حركة انتقال مدمجة لـ sticky headers. لحركة مخصصة، تابع onViewableItemsChanged وقم بتحريك تغيير العنوان باستخدام Animated API أو react-native-reanimated.

هل تؤثر الأقسام الإضافية على أداء SectionList؟

نعم، كل قسم يضيف عنواناً إلى DOM. مع 100+ قسم، ينخفض أداء SectionList بسبب العدد الكبير من العناوين. الحل: قم بتجميع البيانات في 10-20 قسماً منطقياً أو استخدم FlatList مع تجميع مخصص.

الخلاصة

  • SectionList هو مكون React Native لعرض البيانات المجمعة في أقسام مع عناوين و sticky headers
  • بنية الأقسام تتكون من title (عنوان) و data (مصفوفة عناصر)، تُمرر عبر الخاصية sections
  • Sticky headers تثبت عنوان القسم الحالي أثناء التمرير، مما يحسن التنقل في القوائم الطويلة
  • التحسين يتطلب React.memo للعناوين، useMemo للأقسام، و getItemLayout للارتفاع الثابت
  • scrollToLocation يوفر تنقلاً برمجياً إلى أي قسم حسب الفهرس
  • SectionList مقابل FlatList: SectionList للبيانات المصنفة مع عناوين، FlatList للمصفوفات المسطحة
  • الفهرس الأبجدي يُدمج مع SectionList عبر scrollToLocation للتنقل السريع حسب الأحرف

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا