SectionList هو مكون React Native لعرض القوائم المقسمة مع تجميع العناصر حسب الفئات. على عكس FlatList، يقبل SectionList مصفوفة من الأقسام مع عناوين وبيانات، مما يسمح بإنشاء فهارس أبجدية وكتالوجات وقوائم. يدعم المكون sticky headers — العناوين الثابتة أثناء التمرير. اقرأ المزيد عن واجهات برمجة تطبيقات القوائم في الدليل الرسمي من Meta.
الرئيسية
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 العام.
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 للجزء السفلي من كل قسم.
<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 هي ميزة رئيسية في SectionList. عندما يقوم المستخدم بالتمرير، يثبت عنوان القسم الحالي في أعلى الشاشة حتى يتم تمرير القسم بالكامل. يمنح هذا المستخدم سياقاً ثابتاً حول الفئة الحالية.
وضع التثبيت مفعل افتراضياً. لتعطيله، استخدم stickySectionHeadersEnabled={false}. في iOS، تثبت العناوين مع حركة أصلية؛ في Android، عبر معالجة 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 يتبع نفس مبادئ تحسين FlatList، مع فروق دقيقة إضافية تتعلق بالأقسام. كل عنوان قسم هو View إضافي يتم عرضه وإعادة عرضه أثناء التمرير. مع 50+ قسماً، يمكن للعناوين إبطاء التمرير.
استخدم React.memo لـ renderSectionHeader و renderItem لتجنب إعادة العرض غير الضرورية. إذا لم تتغير الأقسام ديناميكياً، فكر في useMemo لمصفوفة الأقسام. للقوائم الكبيرة جداً، ادمج SectionList مع getItemLayout مع تحديد ارتفاعات ثابتة للعناوين والعناصر.
| تقنية التحسين | الوصف | التأثير |
|---|---|---|
| React.memo | حفظ مكونات العناوين والعناصر | يقلل عدد مرات إعادة العرض أثناء التمرير |
| getItemLayout | ارتفاع ثابت للعنوان + العنصر | يلغي القياس، يسرع التمرير إلى الفهرس |
| maxToRenderPerBatch | تحديد العناصر في الدفعة | يمنع التأخير أثناء التمرير السريع |
| windowSize | التقليل إلى 5-10 للقوائم الكبيرة | يقلل عدد العناصر المعروضة في وقت واحد |
الاختيار بين SectionList و FlatList يعتمد على بنية البيانات. إذا كانت البيانات مصفوفة مسطحة — استخدم FlatList. إذا كانت البيانات تتجمع طبيعياً في فئات مع عناوين — استخدم SectionList. لا تستخدم SectionList لقسم واحد — FlatList سيتعامل معه بكفاءة أكبر.
الفرق في الأداء ضئيل عند نفس عدد العناصر. SectionList يضيف حمولة لعرض العناوين، لكن هذه الحمولة مبررة عندما تحمل العناوين معنى. إذا لم تكن العناوين ضرورية — FlatList مع ListHeaderComponent لمحاكاة الأقسام سيكون أسرع.
استخدم SectionList عندما: البيانات مجمعة افتراضياً (جهات اتصال بالحرف)، sticky headers مطلوبة، عناوين الأقسام تحتوي على عناصر تفاعلية (أزرار، مربعات اختيار). استخدم FlatList عندما: البيانات مسطحة، التجميع يتغير ديناميكياً، هناك أكثر من 50 فئة والعناوين متشابهة.
SectionList مع فهرس أبجدي هو حالة استخدام كلاسيكية. يتضمن التنفيذ لوحة جانبية بأحرف و scrollToLocation للقفز إلى قسم. فيما يلي تنفيذ كامل لقائمة جهات اتصال مع تنقل أبجدي.
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 يدعم التغيير الديناميكي للأقسام. عند تغيير مصفوفة الأقسام، يعيد المكون عرض الأقسام المتغيرة فقط. للتشغيل المستقر، استخدم key لكل قسم ولف المكونات في React.memo.
قم بتصفية مصفوفة الأقسام قبل تمريرها: أزل الأقسام ذات data الفارغ. إذا جاءت البيانات من API، تعامل مع التصفية في useMemo. للحالة الفارغة للقائمة بأكملها، استخدم ListEmptyComponent.
Sticky headers على Android مفعلة افتراضياً، لكنها قد لا تعمل عند التعارض مع nestedScrollEnabled. تأكد من أن SectionList غير متداخل داخل ScrollView. على Android 12+، تعمل sticky headers عبر الآلية الأصلية؛ على الإصدارات القديمة، عبر JS.
SectionList لا يوفر حركة انتقال مدمجة لـ sticky headers. لحركة مخصصة، تابع onViewableItemsChanged وقم بتحريك تغيير العنوان باستخدام Animated API أو react-native-reanimated.
نعم، كل قسم يضيف عنواناً إلى DOM. مع 100+ قسم، ينخفض أداء SectionList بسبب العدد الكبير من العناوين. الحل: قم بتجميع البيانات في 10-20 قسماً منطقياً أو استخدم FlatList مع تجميع مخصص.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.