FlatList เป็นคอมโพเนนต์หลักของ React Native สำหรับแสดงรายการประสิทธิภาพสูงพร้อมการทำ virtualization ขององค์ประกอบ แตกต่างจาก ScrollView ตรงที่ FlatList จะเรนเดอร์เฉพาะองค์ประกอบที่มองเห็นบนหน้าจอ ช่วยประหยัดหน่วยความจำและ CPU คอมโพเนนต์รองรับการเลื่อนแนวนอนและแนวตั้ง, pull-to-refresh และการโหลดแบบไม่จำกัด อ่านเพิ่มเติมเกี่ยวกับสถาปัตยกรรมรายการได้ใน เอกสารของ Meta
ประเด็นสำคัญ
FlatList เป็นคอมโพเนนต์ React Native ที่ implements รายการแบบ virtualization ด้วยการเรนเดอร์ประสิทธิภาพสูงสำหรับชุดข้อมูลขนาดใหญ่ คอมโพเนนต์ถูกสร้างบน VirtualizedList และให้ API แบบ declarative สำหรับสร้างรายการแบบแบนที่มีความซับซ้อนทุกระดับ
FlatList ถูกนำมาใช้ใน React Native 0.43 เพื่อแทนที่ ListView ที่เลิกใช้แล้ว ตามข้อมูลของ Meta (2026) FlatList ถูกใช้ใน 85% ของแอปพลิเคชัน React Native ที่ทำงานกับรายการ คอมโพเนนต์รองรับสถานการณ์ทั่วไปทั้งหมด: รายชื่อติดต่อ, ฟีดข่าว, แคตตาล็อกสินค้า และแชท
ก่อน FlatList นักพัฒนาใช้ ListView ซึ่งต้องการการกำหนดค่าการใช้เซลล์ซ้ำด้วยตนเอง FlatList ทำให้กระบวนการนี้เป็นอัตโนมัติโดยใช้การเรนเดอร์แบบหน้าต่างคล้ายกับ RecyclerView ใน Android (2014) และ UICollectionView ใน iOS (2012) ในโปรเจกต์สมัยใหม่ FlatList เป็นมาตรฐานโดยพฤตินัยสำหรับรายการทุกประเภท
FlatList virtualization เป็นกลไกที่คอมโพเนนต์เรนเดอร์เฉพาะองค์ประกอบที่อยู่ในพื้นที่มองเห็นของหน้าจอ บวกกับบัฟเฟอร์ขนาดเล็กในแต่ละด้าน องค์ประกอบที่เหลือจะไม่ถูกสร้างใน DOM ช่วยประหยัดหน่วยความจำและเร่งการเรนเดอร์
เมื่อเลื่อน FlatList จะนำเซลล์ View ที่สร้างไว้แล้วกลับมาใช้ใหม่ โดยแทนที่ข้อมูลของพวกมัน สิ่งนี้ป้องกันการสร้าง View นับพันสำหรับรายการที่มี 10,000 องค์ประกอบ ขนาดบัฟเฟอร์เริ่มต้นคือ 10 องค์ประกอบเหนือและใต้พื้นที่มองเห็น แต่สามารถกำหนดค่าได้ผ่าน windowSize
| พารามิเตอร์ | ค่าเริ่มต้น | คำอธิบาย |
|---|---|---|
| windowSize | 21 | จำนวนหน้าในการเรนเดอร์ (1 หน้า = ความสูงหน้าจอ) |
| initialNumToRender | 10 | จำนวนองค์ประกอบในการเรนเดอร์ครั้งแรก |
| maxToRenderPerBatch | 10 | จำนวนองค์ประกอบสูงสุดที่เรนเดอร์ต่อชุด |
| removeClippedSubviews | false | ลบ View ที่อยู่นอกหน้าจอออกจากลำดับชั้น |
การกำหนดค่าที่เหมาะสมที่สุดของพารามิเตอร์เหล่านี้ช่วยให้สามารถสร้างสมดุลระหว่างความลื่นไหลในการเลื่อนและการใช้หน่วยความจำ สำหรับรายการที่มีองค์ประกอบขนาดใหญ่ แนะนำให้ลด windowSize เหลือ 5-7
FlatList API ประกอบด้วยชุด props สำหรับกำหนดค่าการแสดงผลและพฤติกรรมของรายการ props ที่จำเป็นสองอย่างคือ 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 เพิ่มส่วนหัวและส่วนท้ายให้กับรายการ สิ่งนี้ช่วยให้สร้างเลย์เอาต์ที่ซับซ้อนได้โดยไม่ต้องใช้ wrapper เพิ่มเติม
const styles = StyleSheet.create({
item: {
padding: 16,
backgroundColor: '#fff',
borderBottomWidth: 1,
borderBottomColor: '#e0e0e0',
},
separator: {
height: 1,
backgroundColor: '#ccc',
},
});การปรับแต่ง FlatList มีความสำคัญสำหรับแอปพลิเคชันที่มีองค์ประกอบหลายร้อยและหลายพันรายการ หากไม่มีการกำหนดค่าที่ถูกต้อง รายการอาจช้าเมื่อเลื่อน ใช้หน่วยความจำมากเกินไป และทำให้เกิดการค้างบนอุปกรณ์ระดับล่าง
กฎข้อแรกคือการใช้ 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 แนวนอน ถูกสร้างขึ้นโดยการเพิ่ม prop 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 ที่ถูกเรียกเมื่อองค์ประกอบที่มองเห็นเปลี่ยนแปลง ใช้สำหรับการวิเคราะห์, การโหลดรูปภาพแบบ Lazy และการเปิดใช้งานวิดีโอเฉพาะการ์ดที่มองเห็นเท่านั้น
Pull-to-refresh ใน FlatList ถูก implement ผ่าน props refreshing และ onRefresh ซึ่งทำงานร่วมกับสถานะการโหลด เมื่อดึงรายการลงมา onRefresh จะถูกเรียก และแฟลก refreshing จะบล็อกการเรียกซ้ำ
การเลื่อนแบบไม่จำกัด ถูกกำหนดค่าผ่าน onEndReached — callback ที่ถูกเรียกเมื่อเข้าใกล้จุดสิ้นสุดของรายการ onEndReachedThreshold กำหนดว่าก่อนถึงจุดสิ้นสุดกี่องค์ประกอบเหตุการณ์จะถูกเรียกใช้ โดยทั่วไปจะใช้การแบ่งหน้าตามเคอร์เซอร์
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 ใช้ virtualization — เรนเดอร์เฉพาะองค์ประกอบที่มองเห็น ช่วยประหยัดหน่วยความจำกับชุดข้อมูลขนาดใหญ่ ScrollView เรนเดอร์องค์ประกอบย่อยทั้งหมดพร้อมกัน เหมาะสำหรับรายการขนาดเล็ก 20-30 องค์ประกอบเท่านั้น FlatList เหมาะสมที่สุดสำหรับ 100+ องค์ประกอบ
การกะพริบเกิดขึ้นเมื่อการอ้างอิงถึงอาร์เรย์ข้อมูลเปลี่ยนแปลง ใช้ extraData โดยส่ง dependencies หรือห่อ renderItem ใน React.memo สำหรับการควบคุมอย่างสมบูรณ์ ใช้ useMemo เพื่อทำให้การอ้างอิงข้อมูลคงที่
FlatList ไม่ได้ออกแบบมาให้ซ้อนภายใน ScrollView เนื่องจากความขัดแย้งของท่าทาง วิธีแก้ไข: ใช้ FlatList กับ nestedScrollEnabled (Android), SectionList สำหรับส่วนต่างๆ หรือย้ายการเลื่อนภายนอกไปยัง FlatList ผ่าน ListHeaderComponent
ใช้ Animated API ภายใน renderItem โดยมีความล่าช้าตามดัชนี เมื่อเลื่อน ใช้ onViewableItemsChanged เพื่อเรียกอนิเมชัน ไลบรารี react-native-reanimated และ react-native-lottie ช่วยให้การสร้างอนิเมชันการปรากฏที่ซับซ้อนง่ายขึ้น
VirtualizedList คือคอมโพเนนต์ virtualization พื้นฐานที่ FlatList และ SectionList ถูกสร้างขึ้น FlatList เป็น wrapper ของ VirtualizedList ที่มี API ที่เรียบง่ายสำหรับรายการแบบแบน VirtualizedList ให้การควบคุมระดับต่ำกว่า แต่ไม่ค่อยถูกใช้โดยตรง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ