数据分页是指将大量数据分成多个小块(页)进行加载和显示的技术,主要目的是:
import React, { useState, useEffect } from 'react';
import { FlatList, View, Text, ActivityIndicator } from 'react-native';
const PaginationExample = () => {
const [data, setData] = useState([]);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(false);
const [hasMore, setHasMore] = useState(true);
const fetchData = async () => {
if (!hasMore || loading) return;
setLoading(true);
try {
const response = await fetch(`https://api.example.com/data?page=${page}&limit=10`);
const newData = await response.json();
if (newData.length === 0) {
setHasMore(false);
} else {
setData(prevData => [...prevData, ...newData]);
setPage(prevPage => prevPage + 1);
}
} catch (error) {
console.error('Error fetching data:', error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData();
}, []);
const renderFooter = () => {
if (!loading) return null;
return (
<View style={{ paddingVertical: 20 }}>
<ActivityIndicator size="large" />
</View>
);
};
const handleLoadMore = () => {
if (hasMore && !loading) {
fetchData();
}
};
return (
<FlatList
data={data}
renderItem={({ item }) => (
<View style={{ padding: 20 }}>
<Text>{item.title}</Text>
</View>
)}
keyExtractor={(item, index) => index.toString()}
onEndReached={handleLoadMore}
onEndReachedThreshold={0.5}
ListFooterComponent={renderFooter}
/>
);
};
export default PaginationExample;
page
和 limit
参数cursor
或 after
参数const handleLoadMore = useCallback(() => {
if (hasMore && !loading) {
fetchData();
}
}, [hasMore, loading]);
原因:快速滚动导致多次触发 onEndReached
解决:添加防抖或节流控制
原因:新数据加载导致布局变化
解决:固定列表项高度或使用 getItemLayout
原因:组件卸载时未取消异步操作 解决:使用 AbortController 取消请求
useEffect(() => {
const controller = new AbortController();
const fetchData = async () => {
try {
const response = await fetch(url, { signal: controller.signal });
// 处理响应
} catch (error) {
if (error.name !== 'AbortError') {
console.error('Error:', error);
}
}
};
fetchData();
return () => controller.abort();
}, [url]);
import { useInfiniteQuery } from 'react-query';
const fetchPosts = async ({ pageParam = 1 }) => {
const res = await fetch(`https://api.example.com/posts?page=${pageParam}`);
return res.json();
};
function Posts() {
const {
data,
fetchNextPage,
hasNextPage,
isFetchingNextPage,
} = useInfiniteQuery('posts', fetchPosts, {
getNextPageParam: (lastPage, allPages) => {
return lastPage.hasNext ? allPages.length + 1 : undefined;
},
});
const posts = data?.pages.flatMap(page => page.posts) || [];
return (
<FlatList
data={posts}
renderItem={({ item }) => <PostItem post={item} />}
onEndReached={() => hasNextPage && fetchNextPage()}
ListFooterComponent={() => isFetchingNextPage && <LoadingIndicator />}
/>
);
}
通过以上方法,你可以高效地在 React Native 中实现数据分页功能,提升应用性能和用户体验。
没有搜到相关的文章