Skip to content

Instantly share code, notes, and snippets.

@Blithe-Chiang
Last active June 17, 2024 02:53
Show Gist options
  • Save Blithe-Chiang/9fc2b184dd11456a9337354267d4339f to your computer and use it in GitHub Desktop.
Save Blithe-Chiang/9fc2b184dd11456a9337354267d4339f to your computer and use it in GitHub Desktop.
CFlatList
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>
);
}
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