詳細講一下RN(React Native)中的列表組件FlatList和SectionList

1. FlatList 基礎使用

javascript 复制代码
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';

export const SimpleListDemo: React.FC = () => {
  // 1. 準備數據
  const data = [
    { id: '1', title: '項目 1' },
    { id: '2', title: '項目 2' },
    { id: '3', title: '項目 3' },
  ];

  // 2. 定義如何渲染每一項
  const renderItem = ({ item }) => (
    <View style={styles.item}>
      <Text>{item.title}</Text>
    </View>
  );

  // 3. 渲染 FlatList
  return (
    <FlatList
      data={data}                    // 數據源
      renderItem={renderItem}        // 渲染項
      keyExtractor={item => item.id} // 指定 key
    />
  );
};

const styles = StyleSheet.create({
  item: {
    padding: 20,
    borderBottomWidth: 1,
    borderBottomColor: '#ccc',
  },
});

2. 添加頭部和底部

javascript 复制代码
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';

export const ListWithHeaderFooter: React.FC = () => {
  const data = [/* ... */];

  // 1. 定義頭部組件
  const ListHeader = () => (
    <View style={styles.header}>
      <Text>這是列表頭部</Text>
    </View>
  );

  // 2. 定義底部組件
  const ListFooter = () => (
    <View style={styles.footer}>
      <Text>這是列表底部</Text>
    </View>
  );

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text>{item.title}</Text>
        </View>
      )}
      ListHeaderComponent={ListHeader}   // 添加頭部
      ListFooterComponent={ListFooter}   // 添加底部
      keyExtractor={item => item.id}
    />
  );
};

const styles = StyleSheet.create({
  header: {
    padding: 15,
    backgroundColor: '#f0f0f0',
  },
  item: {
    padding: 20,
    borderBottomWidth: 1,
    borderBottomColor: '#ccc',
  },
  footer: {
    padding: 15,
    backgroundColor: '#f0f0f0',
  },
});

3. 下拉刷新和上拉加載

javascript 复制代码
import React, { useState } from 'react';
import { 
  View, 
  Text, 
  FlatList, 
  RefreshControl, 
  ActivityIndicator, 
  StyleSheet 
} from 'react-native';

export const RefreshLoadMoreList: React.FC = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState([/* 初始數據 */]);

  // 1. 處理下拉刷新
  const onRefresh = async () => {
    setRefreshing(true);
    try {
      // 這裡請求新數據
      const newData = await fetchNewData();
      setData(newData);
    } finally {
      setRefreshing(false);
    }
  };

  // 2. 處理上拉加載更多
  const onLoadMore = async () => {
    if (loading) return;
    setLoading(true);
    try {
      // 這裡請求更多數據
      const moreData = await fetchMoreData();
      setData([...data, ...moreData]);
    } finally {
      setLoading(false);
    }
  };

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text>{item.title}</Text>
        </View>
      )}
      // 下拉刷新配置
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
        />
      }
      // 上拉加載配置
      onEndReached={onLoadMore}
      onEndReachedThreshold={0.1}
      ListFooterComponent={
        loading ? <ActivityIndicator /> : null
      }
    />
  );
};

4. 常用配置項說明

javascript 复制代码
<FlatList
  // 基礎配置
  data={data}                          // 列表數據
  renderItem={renderItem}              // 渲染每一項的方法
  keyExtractor={item => item.id}       // 生成 key 的方法

  // 樣式相關
  contentContainerStyle={styles.list}  // 內容容器樣式
  style={styles.container}             // FlatList 本身樣式

  // 性能優化
  initialNumToRender={10}              // 首次渲染的項目數
  maxToRenderPerBatch={10}             // 每次渲染的最大數量
  windowSize={5}                       // 渲染窗口大小

  // 滾動相關
  showsVerticalScrollIndicator={false} // 是否顯示滾動條
  scrollEnabled={true}                 // 是否可以滾動
/>

5. 空列表處理

javascript 复制代码
import React from 'react';
import { View, Text, FlatList, StyleSheet } from 'react-native';

export const EmptyList: React.FC = () => {
  const data = [];  // 空數據

  const EmptyComponent = () => (
    <View style={styles.empty}>
      <Text>暫無數據</Text>
    </View>
  );

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (/* ... */)}
      ListEmptyComponent={EmptyComponent}  // 當數據為空時顯示
    />
  );
};

const styles = StyleSheet.create({
  empty: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
});

2. SessionList基礎使用

javascript 复制代码
import React from 'react';
import { View, Text, SectionList, StyleSheet } from 'react-native';

export const SimpleSectionList: React.FC = () => {
  // 1. 準備分組數據
  const sections = [
    {
      title: '分組A',
      data: [
        { id: '1', name: '項目A1' },
        { id: '2', name: '項目A2' },
      ]
    },
    {
      title: '分組B',
      data: [
        { id: '3', name: '項目B1' },
        { id: '4', name: '項目B2' },
      ]
    }
  ];

  // 2. 渲染每個項目
  const renderItem = ({ item }) => (
    <View style={styles.item}>
      <Text>{item.name}</Text>
    </View>
  );

  // 3. 渲染分組標題
  const renderSectionHeader = ({ section }) => (
    <View style={styles.header}>
      <Text style={styles.headerText}>{section.title}</Text>
    </View>
  );

  return (
    <SectionList
      sections={sections}                     // 分組數據
      renderItem={renderItem}                 // 渲染每個項目
      renderSectionHeader={renderSectionHeader} // 渲染分組標題
      keyExtractor={item => item.id}          // key提取器
    />
  );
}

const styles = StyleSheet.create({
  item: {
    padding: 15,
    backgroundColor: 'white',
  },
  header: {
    padding: 10,
    backgroundColor: '#f0f0f0',
  },
  headerText: {
    fontSize: 16,
    fontWeight: 'bold',
  },
});

2. 添加分組間距和分隔線

javascript 复制代码
import React from 'react';
import { View, SectionList, StyleSheet } from 'react-native';

export const SectionListWithSeparators: React.FC = () => {
  const sections = [/* ... */];

  // 1. 項目之間的分隔線
  const ItemSeparator = () => (
    <View style={styles.itemSeparator} />
  );

  // 2. 分組之間的間距
  const SectionSeparator = () => (
    <View style={styles.sectionSeparator} />
  );

  return (
    <SectionList
      sections={sections}
      renderItem={renderItem}
      renderSectionHeader={renderSectionHeader}
      ItemSeparatorComponent={ItemSeparator}     // 項目分隔線
      SectionSeparatorComponent={SectionSeparator} // 分組分隔線
      stickySectionHeadersEnabled={true}         // 分組標題固定
    />
  );
};

const styles = StyleSheet.create({
  itemSeparator: {
    height: 1,
    backgroundColor: '#eee',
  },
  sectionSeparator: {
    height: 10,
    backgroundColor: '#f5f5f5',
  },
});

3. 下拉刷新和加載更多

javascript 复制代码
import React, { useState } from 'react';
import { 
  SectionList, 
  RefreshControl, 
  ActivityIndicator 
} from 'react-native';

export const RefreshableSectionList: React.FC = () => {
  const [refreshing, setRefreshing] = useState(false);
  const [loading, setLoading] = useState(false);
  const [sections, setSections] = useState([/* 初始數據 */]);

  // 1. 處理下拉刷新
  const onRefresh = async () => {
    setRefreshing(true);
    try {
      const newData = await fetchNewData();
      setSections(newData);
    } finally {
      setRefreshing(false);
    }
  };

  // 2. 處理加載更多
  const onLoadMore = async () => {
    if (loading) return;
    setLoading(true);
    try {
      const moreData = await fetchMoreData();
      setSections([...sections, ...moreData]);
    } finally {
      setLoading(false);
    }
  };

  return (
    <SectionList
      sections={sections}
      renderItem={renderItem}
      renderSectionHeader={renderSectionHeader}
      // 下拉刷新
      refreshControl={
        <RefreshControl
          refreshing={refreshing}
          onRefresh={onRefresh}
        />
      }
      // 加載更多
      onEndReached={onLoadMore}
      onEndReachedThreshold={0.2}
      ListFooterComponent={
        loading ? <ActivityIndicator /> : null
      }
    />
  );
};

4.空列表和列表頭尾

javascript 复制代码
import React from 'react';
import { View, Text, SectionList } from 'react-native';

export const SectionListWithHeaderFooter: React.FC = () => {
  const sections = [/* ... */];

  // 1. 列表頭部
  const ListHeader = () => (
    <View style={styles.listHeader}>
      <Text>列表頭部</Text>
    </View>
  );

  // 2. 列表底部
  const ListFooter = () => (
    <View style={styles.listFooter}>
      <Text>列表底部</Text>
    </View>
  );

  // 3. 空列表顯示
  const ListEmpty = () => (
    <View style={styles.empty}>
      <Text>暫無數據</Text>
    </View>
  );

  return (
    <SectionList
      sections={sections}
      renderItem={renderItem}
      renderSectionHeader={renderSectionHeader}
      ListHeaderComponent={ListHeader}
      ListFooterComponent={ListFooter}
      ListEmptyComponent={ListEmpty}
    />
  );
};

5. 常用配置項總結

javascript 复制代码
<SectionList
  // 基礎配置
  sections={sections}                        // 分組數據
  renderItem={renderItem}                    // 渲染項目
  renderSectionHeader={renderSectionHeader}  // 渲染分組標題
  keyExtractor={(item) => item.id}          // key提取器

  // 分組相關
  stickySectionHeadersEnabled={true}        // 分組標題是否固定
  renderSectionFooter={renderSectionFooter}  // 渲染分組底部

  // 分隔線
  ItemSeparatorComponent={ItemSeparator}     // 項目分隔線
  SectionSeparatorComponent={SectionSeparator} // 分組分隔線

  // 性能優化
  initialNumToRender={10}                    // 初始渲染數量
  maxToRenderPerBatch={10}                   // 每批渲染數量
  windowSize={5}                             // 渲染窗口大小

  // 樣式相關
  contentContainerStyle={styles.container}   // 內容容器樣式
  style={styles.list}                        // 列表樣式
/>
相关推荐
yqcoder21 分钟前
Commander 一款命令行自定义命令依赖
前端·javascript·arcgis·node.js
前端Hardy37 分钟前
HTML&CSS :下雪了
前端·javascript·css·html·交互
码上飞扬2 小时前
Vue 3 30天精进之旅:Day 05 - 事件处理
前端·javascript·vue.js
程序员小寒2 小时前
由于请求的竞态问题,前端仔喜提了一个bug
前端·javascript·bug
python算法(魔法师版)6 小时前
React应用深度优化与调试实战指南
开发语言·前端·javascript·react.js·ecmascript
阿芯爱编程10 小时前
vue3 vue2区别
前端·javascript·vue.js
不叫猫先生11 小时前
【React】PureComponent 和 Component 的区别
前端·javascript·react.js·前端框架
瓴翎玲11 小时前
CSS(二)——选择器
前端·javascript·css
杰九16 小时前
【全栈】SprintBoot+vue3迷你商城(9)
前端·javascript·vue.js·spring boot
掉落的牙16 小时前
android studio本地打包后,无法热更,无法执行换包操作,plus.runtime.install没有弹窗
前端·javascript·android studio