8. FlatList и списки
FlatList — виртуализированный список для больших наборов данных. Рендерит только видимые элементы, остальные уничтожает. Обязателен при >50 элементах.
FlatList — основы
Заголовок раздела «FlatList — основы»import { FlatList, Text, View, StyleSheet } from 'react-native';
const data = [ { id: '1', title: 'Элемент 1' }, { id: '2', title: 'Элемент 2' }, // ...];
<FlatList data={data} keyExtractor={(item) => item.id} renderItem={({ item, index }) => ( <View style={styles.item}> <Text>{item.title}</Text> </View> )}/>Горизонтальный список
Заголовок раздела «Горизонтальный список»<FlatList horizontal={true} showsHorizontalScrollIndicator={false} data={stories} keyExtractor={(item) => item.id} renderItem={({ item }) => <StoryCard story={item} />} contentContainerStyle={{ paddingHorizontal: 16, gap: 12 }}/>Pull to Refresh
Заголовок раздела «Pull to Refresh»import { FlatList, RefreshControl } from 'react-native';
const [refreshing, setRefreshing] = useState(false);
const onRefresh = async () => { setRefreshing(true); await fetchData(); setRefreshing(false);};
<FlatList data={data} renderItem={renderItem} keyExtractor={(item) => item.id} refreshControl={ <RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor="#cba6f7" /> }/>SectionList — список с секциями
Заголовок раздела «SectionList — список с секциями»import { SectionList, Text, View } from 'react-native';
const sections = [ { title: 'Сегодня', data: ['Задача 1', 'Задача 2'] }, { title: 'Вчера', data: ['Задача 3'] },];
<SectionList sections={sections} keyExtractor={(item, index) => item + index} renderItem={({ item }) => ( <View style={styles.item}> <Text>{item}</Text> </View> )} renderSectionHeader={({ section: { title } }) => ( <Text style={styles.sectionHeader}>{title}</Text> )}/>Пагинация и infinite scroll
Заголовок раздела «Пагинация и infinite scroll»const [data, setData] = useState([]);const [page, setPage] = useState(1);const [loading, setLoading] = useState(false);const [hasMore, setHasMore] = useState(true);
const loadMore = async () => { if (loading || !hasMore) return; setLoading(true); const newData = await fetchPage(page); if (newData.length === 0) setHasMore(false); setData(prev => [...prev, ...newData]); setPage(p => p + 1); setLoading(false);};
<FlatList data={data} renderItem={renderItem} keyExtractor={(item) => item.id} onEndReached={loadMore} onEndReachedThreshold={0.5} // Загружать когда 50% до конца ListFooterComponent={loading ? <ActivityIndicator /> : null}/>Performance
Заголовок раздела «Performance»<FlatList data={data} renderItem={renderItem} keyExtractor={(item) => item.id}
// Оптимизации производительности: removeClippedSubviews={true} // Unmount невидимые элементы (Android) maxToRenderPerBatch={10} // Элементов за один рендер батч updateCellsBatchingPeriod={50} // ms между батчами windowSize={10} // Размер окна рендера (в экранах) initialNumToRender={10} // Первоначальный рендер getItemLayout={(data, index) => ({ // Если высота фиксирована length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index, })}/>FlashList — супер FlatList
Заголовок раздела «FlashList — супер FlatList»FlashList от Shopify — замена FlatList с 10x лучшей производительностью:
npx expo install @shopify/flash-listimport { FlashList } from "@shopify/flash-list";
<FlashList data={data} renderItem={({ item }) => <Item item={item} />} estimatedItemSize={80} // Примерная высота элемента/>