Last active
June 17, 2024 02:53
-
-
Save Blithe-Chiang/9fc2b184dd11456a9337354267d4339f to your computer and use it in GitHub Desktop.
CFlatList
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useMemoizedFn, useMount, useUnmountedRef } from "ahooks"; | |
import React, { useState } from "react"; | |
import { FlatList, FlatListProps } from "react-native"; | |
interface CFlatListProps<ItemT> { | |
onFetch: ( | |
isRefresh: boolean, | |
success: (data: ItemT[], pageSize: number) => void, | |
fail: (err: string) => void | |
) => void; | |
} | |
export default function CFlatList<ItemT>( | |
props: CFlatListProps<ItemT> & | |
Omit<FlatListProps<ItemT>, "data" | "onRefresh"> | |
) { | |
const { onFetch, onEndReached, ...restProps } = props; | |
// 列表的数据 | |
const [listData, setListData] = useState<ItemT[]>([]); | |
// 是否加载中 | |
const [refreshing, setRefreshing] = useState(false); | |
// 初始化的时候加载数据 | |
useMount(() => { | |
_onFetch(true); | |
}) | |
const [hasMore, setHasMore] = useState(false); | |
const unmountedRef = useUnmountedRef(); | |
// 成功的情况 | |
const success = useMemoizedFn( | |
(_data: any[], pageSize: number, isRefresh: boolean) => { | |
if (unmountedRef.current) return; | |
// 更新数据 | |
if (isRefresh) { | |
setListData(_data); | |
} else { | |
setListData([...listData, ..._data]); | |
} | |
// 设置是否还有更多数据 | |
const hasMore = _data.length >= pageSize; | |
setHasMore(hasMore); | |
setRefreshing(false); | |
} | |
); | |
// 失败的情况 | |
const fail = useMemoizedFn(() => { | |
if (unmountedRef.current) return; | |
setRefreshing(false); | |
}); | |
// 加载数据 | |
const _onFetch = useMemoizedFn((isRefresh = false) => { | |
if (!isRefresh) { | |
// 如果没有更多数据了,就不再请求 | |
if (!hasMore) { | |
return; | |
} | |
} | |
onFetch( | |
isRefresh, | |
(data, pageSize) => { | |
success(data, pageSize, isRefresh); | |
}, | |
fail | |
); | |
}); | |
return ( | |
<FlatList | |
style={{ backgroundColor: "#bbfa", width: "100%" }} | |
data={listData} | |
refreshing={refreshing} | |
onRefresh={() => { | |
_onFetch(true); | |
}} | |
onEndReached={(info) => { | |
onEndReached?.(info); | |
_onFetch(false); | |
}} | |
{...restProps} | |
></FlatList> | |
); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Text, View } from "react-native"; | |
import CFlatList from "./CFlatList"; | |
export default function Index() { | |
const onFetch = (isRefresh: boolean, success: (data: any[], pageSize: number) => void, fail: (err: string) => void): void => { | |
if (isRefresh) { | |
success(getData(20), 20); | |
return | |
} | |
success(getData(10), 10) | |
}; | |
return ( | |
<View | |
style={{ | |
flex: 1, | |
justifyContent: "center", | |
alignItems: "center", | |
}} | |
> | |
<CFlatList<{ id: number, title: string }> | |
keyExtractor={(item) => item.id + ""} | |
renderItem={({ item }) => <Text style={{ | |
height: 50, | |
}}>{item.title}</Text>} | |
onFetch={onFetch} /> | |
</View> | |
); | |
} | |
function getData(size: number = 10) { | |
// generate random values | |
return Array.from({ length: size }, (_, i) => { | |
const id = Math.random(); | |
return { | |
title: `title ${id + 1}`, | |
id: id + 1, | |
}; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment