FlatList — کامپوننت اصلی React Native برای نمایش لیستهای پربازده با مجازیسازی عناصر. برخلاف ScrollView، FlatList فقط عناصر قابل مشاهده صفحه را رندر میکند و در حافظه و پردازنده صرفهجویی میکند. این کامپوننت از اسکرول افقی و عمودی، pull-to-refresh و بارگذاری بینهایت پشتیبانی میکند. درباره معماری لیستها در مستندات Meta بیشتر بخوانید.
نکات اصلی
FlatList — کامپوننت React Native که یک لیست مجازیسازی شده با رندرینگ پربازده حجم زیادی از دادهها را پیادهسازی میکند. این کامپوننت بر پایه VirtualizedList ساخته شده و یک API اعلامی برای ایجاد لیستهای تخت با هر پیچیدگی ارائه میدهد.
FlatList در React Native 0.43 به عنوان جایگزین ListView قدیمی ظاهر شد. طبق دادههای Meta (2026)، FlatList در 85% از برنامههای React Native که با لیستها کار میکنند استفاده میشود. این کامپوننت از همه سناریوهای رایج پشتیبانی میکند: مخاطبین، فیدهای خبری، کاتالوگ محصولات، چتها.
قبل از ظهور FlatList، توسعهدهندگان از ListView استفاده میکردند که نیاز به پیکربندی دستی استفاده مجدد از سلولها داشت. FlatList این فرآیند را خودکار کرد و رندرینگ پنجرهای را مشابه RecyclerView در اندروید (2014) و UICollectionView در iOS (2012) پیادهسازی کرد. در پروژههای مدرن، FlatList استاندارد واقعی برای هر نوع لیستی است.
مجازیسازی FlatList — مکانیزمی که در آن کامپوننت فقط عناصری را که در ناحیه قابل مشاهده صفحه قرار میگیرند، به علاوه یک بافر کوچک در هر طرف، رندر میکند. عناصر باقیمانده در DOM ایجاد نمیشوند که این امر باعث صرفهجویی در حافظه و تسریع رندرینگ میشود.
در هنگام اسکرول، FlatList از سلولهای View از پیش ایجاد شده مجدداً استفاده میکند و دادههای داخل آنها را جایگزین میکند. این کار از ایجاد هزاران View برای لیستی با ۱۰٬۰۰۰ عنصر جلوگیری میکند. اندازه بافر پیشفرض ۱۰ عنصر در بالا و پایین ناحیه قابل مشاهده است، اما از طریق windowSize قابل پیکربندی است.
| پارامتر | پیشفرض | توضیحات |
|---|---|---|
| windowSize | 21 | تعداد صفحات برای رندرینگ (۱ صفحه = ارتفاع صفحه) |
| initialNumToRender | 10 | تعداد عناصر در اولین رندر |
| maxToRenderPerBatch | 10 | حداکثر عناصر رندر شده در یک دسته |
| removeClippedSubviews | false | حذف Viewهای خارج از صفحه از سلسلهمراتب |
پیکربندی بهینه این پارامترها امکان ایجاد تعادل بین روانی اسکرول و مصرف حافظه را فراهم میکند. برای لیستهایی با عناصر بزرگ، توصیه میشود windowSize را به ۵-۷ کاهش دهید.
API FlatList شامل مجموعهای از پراپها برای پیکربندی نمایش و رفتار لیست است. دو پراپ اجباری — data (آرایه داده) و renderItem (تابع رندرینگ عنصر). keyExtractor با ارائه یک کلید منحصربهفرد برای هر عنصر، عملکرد را افزایش میدهد.
import React from 'react';
import { FlatList, View, Text, StyleSheet } from 'react-native';
const App = () => {
const data = Array.from({ length: 100 }, (_, i) => ({
id: i.toString(),
title: `Item #${i + 1}`,
}));
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={styles.item}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={item => item.id}
ItemSeparatorComponent={() => <View style={styles.separator} />}
/>
);
};ItemSeparatorComponent جداکننده بین عناصر را اضافه میکند، ListHeaderComponent و ListFooterComponent — هدر و فوتر لیست. این امکان ایجاد طرحبندیهای پیچیده بدون لفافه اضافی را فراهم میکند.
const styles = StyleSheet.create({
item: {
padding: 16,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
separator: {
height: 1,
backgroundColor: '#ccc',
},
});بهینهسازی FlatList برای برنامههایی با صدها و هزاران عنصر حیاتی است. بدون پیکربندی صحیح، لیست ممکن است هنگام اسکرول کند شود، حافظه اضافی مصرف کند و در دستگاههای ضعیف دچار crash شود.
اولین قانون — استفاده از keyExtractor با شناسههای منحصربهفرد و پایدار. استفاده از ایندکسها به عنوان کلید منجر به استفاده مجدد نادرست از سلولها و باگهای وضعیتی میشود. دوم — قرار دادن renderItem در useCallback و استفاده از React.memo برای کامپوننت عنصر.
اگر همه عناصر ارتفاع یکسانی دارند، getItemLayout به FlatList اجازه میدهد موقعیت اسکرول را بدون اندازهگیری کامپوننتها محاسبه کند. این افزایش عملکرد قابل توجهی به ویژه هنگام اسکرول به یک ایندکس خاص میدهد.
const ITEM_HEIGHT = 80;
const getItemLayout = (data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
});
<FlatList
data={data}
getItemLayout={getItemLayout}
renderItem={renderItem}
/FlatList>useMemo برای دادهها از رندرهای مجدد غیرضروری جلوگیری میکند. اگر دادهها از API میآیند، آنها را یکبار تبدیل و کش کنید. از React.memo برای کامپوننت عنصر استفاده کنید تا از رندر شدن عناصر تغییرنیافته جلوگیری شود.
FlatList افقی با افزودن پراپ horizontal={true} ایجاد میشود. لیست جهت اسکرول را به محور X تغییر میدهد که برای کاروسلهای محصولات، گالریهای تصاویر و منوهای افقی مناسب است.
در حالت افقی، پیکربندی صحیح snapToInterval و snapToAlignment برای اسکرول گامبهگام مانند کاروسلهای بومی مهم است. کامپوننت به طور خودکار شتاب و رها کردن انگشت را مدیریت میکند و در نزدیکترین عنصر متوقف میشود.
<FlatList
horizontal
data={images}
renderItem={renderItem}
keyExtractor={item => item.id}
showsHorizontalScrollIndicator={false}
snapToInterval={CARD_WIDTH + GAP}
snapToAlignment="start"
decelerationRate="fast"
pagingEnabled
onViewableItemsChanged={onViewableItemsChanged}
/>onViewableItemsChanged — callback که هنگام تغییر عناصر قابل مشاهده فراخوانی میشود. برای تحلیل، بارگذاری تنبل تصاویر و فعالسازی ویدئو فقط برای کارتهای قابل مشاهده استفاده میشود.
Pull-to-refresh در FlatList از طریق پراپهای refreshing و onRefresh پیادهسازی میشود که با وضعیت بارگذاری کار میکنند. هنگام کشیدن لیست به پایین، onRefresh فراخوانی میشود و پرچم refreshing از فراخوانیهای تکراری جلوگیری میکند.
بارگذاری بینهایت (infinite scroll) از طریق onEndReached پیکربندی میشود — callback که هنگام نزدیک شدن به انتهای لیست فعال میشود. onEndReachedThreshold تعیین میکند چند عنصر قبل از انتها رویداد را فعال کند. برای صفحهبندی معمولاً از رویکرد cursor-based استفاده میشود.
const ListWithPagination = () => {
const [data, setData] = React.useState([]);
const [page, setPage] = React.useState(1);
const [refreshing, setRefreshing] = React.useState(false);
const loadMore = React.useCallback(async () => {
const newData = await fetchPage(page);
setData(prev => [...prev, ...newData]);
setPage(p => p + 1);
}, [page]);
return (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={item => item.id}
refreshing={refreshing}
onRefresh={loadMore}
onEndReached={loadMore}
onEndReachedThreshold={0.5}
/>
);
};مهم: onEndReached ممکن است چندین بار فراخوانی شود. برای جلوگیری از درخواستهای تکراری تا پایان درخواست قبلی، پرچم isLoading اضافه کنید. از ActivityIndicator در ListFooterComponent برای نشان دادن بارگذاری استفاده کنید.
سوالات متداول
FlatList از مجازیسازی استفاده میکند — فقط عناصر قابل مشاهده را رندر میکند که در دادههای بزرگ در حافظه صرفهجویی میکند. ScrollView همه عناصر فرزند را یکباره رندر میکند و فقط برای لیستهای کوچک تا ۲۰-۳۰ عنصر مناسب است. FlatList برای ۱۰۰+ عنصر بهینه است.
چشمک زدن هنگام تغییر مرجع آرایه data رخ میدهد. از extraData استفاده کنید و وابستگی را به آن منتقل کنید، یا renderItem را در React.memo قرار دهید. برای کنترل کامل از useMemo برای تثبیت مراجع داده استفاده کنید.
FlatList به دلیل تداخل ژستها برای قرارگیری در ScrollView طراحی نشده است. راهحلها: از FlatList با nestedScrollEnabled (اندروید)، SectionList برای بخشها، یا انتقال اسکرول خارجی به FlatList از طریق ListHeaderComponent استفاده کنید.
در داخل renderItem از Animated API با تأخیر بر اساس ایندکس استفاده کنید. هنگام اسکرول از onViewableItemsChanged برای راهاندازی انیمیشن استفاده کنید. کتابخانههای react-native-reanimated و react-native-lottie ایجاد انیمیشنهای پیچیده ظاهرشدن را ساده میکنند.
VirtualizedList — کامپوننت پایه مجازیسازی است که FlatList و SectionList بر روی آن ساخته شدهاند. FlatList یک پوسته برای VirtualizedList با API سادهشده برای لیستهای تخت است. VirtualizedList کنترل سطح پایینتری ارائه میدهد اما به ندرت مستقیماً استفاده میشود.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید