SectionList — کامپوننت React Native برای نمایش لیستهای بخشبندی شده با گروهبندی عناصر بر اساس دستهبندیها. بر خلاف FlatList، SectionList آرایهای از بخشها با عنوانها و دادهها دریافت میکند که امکان ایجاد نمایههای الفبایی، کاتالوگها و منوها را فراهم میکند. این کامپوننت از sticky headers — عنوانهای ثابت در هنگام اسکرول پشتیبانی میکند. برای اطلاعات بیشتر درباره API لیستها به راهنمای رسمی 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. هنگامی که کاربر اسکرول میکند، عنوان بخش فعلی به لبه بالای صفحه میچسبد تا زمانی که بخش به طور کامل اسکرول شود. این به کاربر زمینه ثابتی درباره دستهبندی فعلی میدهد.
حالت sticky به طور پیشفرض فعال است. برای غیرفعال کردن از 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 را برای آرایه sections در نظر بگیرید. برای لیستهای بسیار بزرگ، 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 از تغییرات پویای بخشها پشتیبانی میکند. هنگام تغییر آرایه sections، کامپوننت فقط بخشهای تغییر یافته را دوباره رندر میکند. برای عملکرد پایدار از key برای هر بخش استفاده کنید و کامپوننتها را در React.memo بپیچید.
آرایه sections را قبل از ارسال فیلتر کنید: بخشهای با data خالی را حذف کنید. اگر دادهها از API میآیند، فیلتر کردن را در useMemo انجام دهید. برای حالت خالی کل لیست از ListEmptyComponent استفاده کنید.
Sticky headers در Android به طور پیشفرض فعال هستند، اما ممکن است در تضاد با nestedScrollEnabled کار نکنند. مطمئن شوید SectionList در ScrollView تو در تو نیست. در Android 12+ sticky headers از طریق مکانیزم بومی کار میکنند، در نسخههای قدیمیتر — از طریق JS.
SectionList انیمیشن داخلی تغییر sticky header را ارائه نمیدهد. برای انیمیشن سفارشی، onViewableItemsChanged را ردیابی کنید و تغییر عنوان را از طریق Animated API یا react-native-reanimated انیمیشن کنید.
بله، هر بخش یک عنوان به DOM اضافه میکند. در 100+ بخش، عملکرد SectionList به دلیل تعداد زیاد عنوانها کاهش مییابد. راهحل: دادهها را در 10–20 بخش منطقی گروهبندی کنید یا از FlatList با گروهبندی سفارشی استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید