FlatList组件
import React, { FC, useEffect, useState, useRef } from 'react'; import { ActivityIndicator, FlatList as RNFlastList, FlatListProps } from 'react-native'; import { Text, View, ViewProps } from 'react-native-ui-lib'; import { ViewLoader, WidthSpace } from '..'; type IFlatListWithRematchProps<T = any> = FlatListProps<T> & { flex?: boolean; pageSize?: number; // 每页展示个数 onEndCB?: () => void; // 每次分页执行的回调 fetchDataFn: any; currentPageNo: number; totalCount: number; pageToNextFn: any; loading: boolean; isNeedBigLoading: boolean; triggerPageNo: number; triggerListType?: string; }; // 分页组件 const FlatList: FC<IFlatListWithRematchProps> = ({ flex = true, pageSize = 10, fetchDataFn, // 接口调用函数,封装为promise,执行.then处理接口返回的数据 pageToNextFn, // 上滑加载执行的函数 triggerPageNo, // 用于触发接口调用函数的执行,一旦监听到外部pageNo更新,接口调用函数重新执行 triggerListType, // 用于页面存在多个tab,在切换tab时,需要分页组件同样监听到外部pageNo更新,接口调用函数重新执行, 如果页面不存在tab则用不到这个参数 loading, isNeedBigLoading = false, //是否在 ViewLoader上面加 loading onEndCB, // 上滑加载完成后的额外执行函数 ...restProps }) => { const [currentPageNo, setCurrentPageNo] = useState(1); const [totalCount, setTotalCount] = useState(0); const [results, setResults] = useState([]); const totalPage = Math.ceil(totalCount / pageSize); const flatListRef = useRef<any>(); useEffect(() => { if (triggerPageNo > 0 && totalPage > 0 && triggerPageNo >= totalPage) return; fetchDataFn.then((res: { pageNo: number; totalCount: number; results: [] }) => { setCurrentPageNo(res.pageNo); setTotalCount(res.totalCount); setResults(res.results); }); // 重新从头开始请求时,页面滚动到顶部 if (triggerPageNo === 0) { flatListRef?.current?.scrollToOffset({ animated: false, offset: 0 }); } return () => { console.log('clear'); }; }, [triggerPageNo, triggerListType]); useEffect(() => { // 切换tab时,要求列表上滑到顶部 if (triggerListType) { flatListRef?.current?.scrollToOffset({ animated: true, offset: 0 }); } }, [triggerListType]); const onEndReached = () => { if (currentPageNo < totalPage) { onNext(); onEndCB && onEndCB(); } }; const onNext = () => { pageToNextFn(); }; const emptyComponent = () => { if (!loading && totalCount === 0) { return ( <View center padding-30 paddingT-120> <Text artTitle grey99> 暂无更多数据... </Text> </View> ); } return <View />; }; const footerComponent = () => { //console.log('footerComponent', currentPageNo, totalPage); if (currentPageNo < totalPage || loading) // return ( <View row center padding-15> <ActivityIndicator size="small" /> <WidthSpace /> <Text artTitle grey99> 正在加载中... </Text> </View> ); if (currentPageNo === totalPage && currentPageNo !== 0 && totalPage > 0) { return ( <View padding-15 center> <Text artTitle grey99> 没有更多了... </Text> </View> ); } return <View></View>; }; // loading={loading} 不使用View层的loading,分页统一使用分页自己的小loading return ( <ViewLoader flex={flex} loading={isNeedBigLoading ? loading : false}> <RNFlastList ref={flatListRef} data={results} onEndReached={onEndReached} onEndReachedThreshold={0.2} ListFooterComponent={footerComponent} ListEmptyComponent={emptyComponent} {...restProps} /> </ViewLoader> ); }; export const NoData: FC<ViewProps & { title?: string }> = ({ title = '暂无更多数据...', ...restProps }) => ( <View center padding-30 {...restProps}> <Text artTitle grey99> {title} </Text> </View> ); export const onl oad: FC<ViewProps & { title?: string; loading?: boolean }> = ({ loading = false, title = '正在加载中...', }) => { if (loading) return ( <View row center padding-15> <ActivityIndicator size="small" /> <WidthSpace /> <Text artTitle grey99> {title} </Text> </View> ); return <></>; }; export default FlatList;
FlatListDemo
// 社区Tab下 动态Tab页 import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; // @ts-ignore import { RefreshNormalHeader } from 'react-native-smart-refresh'; import { View, Colors } from 'react-native-ui-lib'; import { DispatchPro, RootState } from '../../../store'; import { WidthSpace, LineSpace, FlatList } from '../../../components'; import { IDaynamicItem } from '../../../models/community/ICommunity.module'; import DaynamicItem from '../components/daynamicItem';type ICommunity = ReturnType<typeof mapStateToProps> & ReturnType<typeof mapDispatchToProps>; const Daynamic = (props: ICommunity) => { const { fetchDaynamicCarousel, fetchAnnouncementList, fetchDaynamicList, daynamicLoading, shareStatus } = props;
const [daynamicList, setDaynamicList] = useState<IDaynamicItem[]>([]); // 动态列表数据 const [currentPageNo, setCurrentPageNo] = useState(-1); // 动态列表分页 // 页面初始化时,请求数据 const initRequest = () => { fetchDaynamicCarousel({ params: { pageTypeId: '1', // 页面类型;1-动态头部广告;2-文化每日分享运营位 }, apiName: 'fetchDaynamicCarousel', }); fetchAnnouncementList({ params: {}, apiName: 'fetchAnnouncementList', }); };
useEffect(() => { initRequest(); setCurrentPageNo(0); }, []); useEffect(() => { if (shareStatus === 'success') { onRefresh(); } }, [shareStatus]); const onRefresh = () => { setDaynamicList([]); setCurrentPageNo(-1); setTimeout(() => { initRequest(); setCurrentPageNo(0); }, 500); };
// 请求动态列表数据,距离底部还有0.2 时触发 注意此参数是一个比值而非像素单位。比如,0.5 表示距离内容最底部的距离为当前列表可见长度的一半时触发。 const fetchDataFn = React.useMemo(() => new Promise((resolve) => { if (currentPageNo < 0) return; fetchDaynamicList && fetchDaynamicList({ params: { pageNo: currentPageNo + 1, pageSize: 10, pageTypeId: '1', associationId: '' }, apiName: 'fetchDaynamicList', }).then(res => { setDaynamicList([...daynamicList, ...(res?.shareInfoList || [])]); resolve({ pageNo: currentPageNo + 1, totalCount: res?.totalCount, results: [...daynamicList, ...(res?.shareInfoList || [])], }); }); }), [currentPageNo]);
const pageToNextFn = () => { setCurrentPageNo(currentPageNo + 1); }; return ( <FlatList loading={daynamicLoading} isNeedBigLoading refreshControl={ <RefreshNormalHeader refreshing={daynamicLoading} onRefresh={onRefresh} containerStyle={{ paddingLeft: 10, paddingBottom: 30, alignItems: 'flex-end', }} titleStyle={{ fontSize: 14 }} timeStyle={{ display: 'none', fontSize: 14 }} leftContainerStyle={{ marginBottom: -6, marginRight: -35 }} activityIndicatorProps={{ color: Colors.primaryColor }} /> } fetchDataFn={fetchDataFn} pageToNextFn={pageToNextFn} triggerPageNo={currentPageNo} keyExtractor={(item: IDaynamicItem, index: number) => `${item.shareId}_${item.typeId}_${index}`} renderItem={({ item }: { item: IDaynamicItem }) => { return <View> <LineSpace height={15} /> <View row> <WidthSpace width={15} /> <DaynamicItem data={item} /> </View> </View>; }} /> ); };
const mapStateToProps = ({ community: { daynamicCarouselData, announcementSingleData, daynamicList, daynamicLoading, shareStatus }, }: RootState) => ({ daynamicCarouselData, announcementSingleData, daynamicList, daynamicLoading, shareStatus }); const mapDispatchToProps = ({ community: { fetchDaynamicCarousel, fetchAnnouncementList, fetchDaynamicList }, }: DispatchPro) => ({ fetchDaynamicCarousel, fetchAnnouncementList, fetchDaynamicList, });
export default connect(mapStateToProps, mapDispatchToProps)(Daynamic);
标签:loading,return,FlatList,..,--,currentPageNo,React,import,const From: https://www.cnblogs.com/zpy521hl/p/16873673.html