RN使用FlatList实现上拉加载更多的代码

540 阅读2分钟

使用ScrollView实现

import React, { useState, useCallback } from 'react';
import { ScrollView, ActivityIndicator, View, Text, StyleSheet } from 'react-native';

const LoadMoreScrollView = () => {
  // 设置状态来控制加载指示器是否显示
  const [loading, setLoading] = useState(false);
  // 设置状态来存储列表数据
  const [data, setData] = useState(Array.from({ length: 20 }, (_, index) => index));

  // 处理加载更多的回调函数
  const handleLoadMore = useCallback(() => {
    // 设置加载状态为true,显示加载指示器
    setLoading(true);
    // 模拟加载更多数据,这里使用setTimeout来模拟异步操作
    setTimeout(() => {
      // 更新数据状态,将新数据添加到现有数据数组中
      setData((prevData) => [
        ...prevData,
        // 创建一个新的数组来表示加载更多的数据
        ...Array.from({ length: 20 }, (_, index) => index + prevData.length),
      ]);
      // 加载完成后,设置加载状态为false,隐藏加载指示器
      setLoading(false);
    }, 2000);
  }, []);

  // 处理滚动的回调函数
  const handleScroll = ({ nativeEvent }) => {
    // 判断是否滚动到底部
    // 当nativeEvent.contentOffset.y(内容的向上滚动的高度)等于nativeEvent.contentSize.height(内容的总高度)减去nativeEvent.layoutMeasurement.height(ScrollView的剩余可见高度)时,意味着已经滚动到了底部。这时,可以触发加载更多的操作。
    if (nativeEvent.contentOffset.y >= nativeEvent.contentSize.height - nativeEvent.layoutMeasurement.height) {
      // 如果当前没有在加载中,则调用加载更多的函数
      if (!loading) {
        // 节流调用方法
        handleLoadMore();
      }
    }
  };

  return (
    <ScrollView
      // 添加滚动事件监听
      onScroll={handleScroll}
      // 设置滚动事件节流优化性能
      scrollEventThrottle={16}
      // 设置样式
      style={styles.container}
    >
      {data.map((item, index) => (
        // 渲染每个列表项
        <View key={index} style={styles.item}>
          <Text>{item}</Text>
        </View>
      ))}
      {/* 如果正在加载,则显示加载指示器 */}
      {loading && (
        <ActivityIndicator size="large" style={styles.loader} />
      )}
    </ScrollView>
  );
};

// 创建样式表
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  item: {
    height: 100, // 设置列表项的高度
    justifyContent: 'center', // 垂直居中内容
    alignItems: 'center', // 水平居中内容
    borderBottomWidth: 1, // 添加底部边框
    borderBottomColor: '#ccc', // 设置边框颜色
  },
  loader: {
    marginVertical: 20, // 设置加载指示器的垂直外边距
  },
});

// 导出组件
export default LoadMoreScrollView;

使用FlatList实现

import React, { useState, useEffect } from 'react';
import { FlatList, View, Text, ActivityIndicator, StyleSheet } from 'react-native';

const MyComponent = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [page, setPage] = useState(1);

  const fetchData = () => {
    setLoading(true);
    // 模拟从API获取数据
    setTimeout(() => {
      const newData = Array.from({ length: 10 }, (_, index) => ({ id: index + 1, text: `Item ${index + 1}` }));
      setData([...data, ...newData]);
      setLoading(false);
    }, 1000);
  };

  const handleLoadMore = () => {
    if (!loading) {
      setPage(page + 1);
      fetchData();
    }
  };

  useEffect(() => {
    fetchData();
  }, []);

  const renderFooter = () => {
    return loading ? (
      <View style={styles.footer}>
        <ActivityIndicator size="large" color="blue" />
      </View>
    ) : null;
  };

  return (
    <FlatList
      data={data}
      renderItem={({ item }) => (
        <View style={styles.item}>
          <Text>{item.text}</Text>
        </View>
      )}
      keyExtractor={(item) => item.id.toString()}
      onEndReached={handleLoadMore}
      onEndReachedThreshold={0.1}
      ListFooterComponent={renderFooter}
    />
  );
};

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

export default MyComponent;