引言
在前端开发中,下拉刷新是一项非常常见的功能。
虽然现在 React 有很多库可以实现这个功能,但它们存在着一些问题:
- 大多数带有下拉刷新功能的组件都是UI库,因此在引入下拉刷新组件后,往往需要引入整个UI库,会增加许多不必要的依赖。
- 这些库中大部分的自定义程度都很低,如果想要自定义下拉动画效果,会非常麻烦。
- 需要对下拉容器设置高度,无法利用父容器的滚动。
为了解决上述问题,ReactPullToRefreshify 诞生了
优点
ReactPullToRefreshify它有以下优点👇:
- 这是一个极简的React下拉刷新组件,不依赖于其他库。
- 它的 API 设计与 Ant Design Mobile 相似,可定制化程度更高。
- 而且压缩后的文件大小只有2kb,适用于手机端和电脑端。
安装
那下面让我们来看看怎么安装使用吧!👀
$ npm i react-pull-to-refreshify
# or
$ yarn add react-pull-to-refreshify
基础使用
import { PullToRefreshify } from "react-pull-to-refreshify";
function renderText(pullStatus, percent) {
switch (pullStatus) {
case "pulling":
return (
<div>
{`下拉即可刷新 `}
<span style={{ color: "green" }}>{`${percent.toFixed(0)}%`}</span>
</div>
);
case "canRelease":
return "释放即可刷新...";
case "refreshing":
return "刷新中";
case "complete":
return "刷新成功";
default:
return "";
}
}
const [refreshing, setRefreshing] = useState(false);
function handleRefresh() {
setRefreshing(true);
setTimeout(() => {
setRefreshing(false);
}, 2000);
}
<PullToRefreshify
refreshing={refreshing}
onRefresh={handleRefresh}
renderText={renderText}
>
{list.map((item, i) => (
<div key={item.id}>{item}</div>
))}
</PullToRefreshify>;
自定义动画效果
动画效果1
动画效果2
加载更多
上拉加载
小伙伴们可能关心另一件事情,那么这个组件支不支持上拉加载更多功能呢?
为了尽可能地保持小而精,这个库本身是不支持上拉加载更多的功能。
但你可以很容易地和 react-intersection-observer 结合去实现上拉加载功能,让专业人去做专业的事。
下面我们可以简单地看看如何利用 react-intersection-observer 的 useInView 去实现上拉加载更多功能。
在线预览地址 codesandbox.io/s/mystifyin…
import { useInView } from "react-intersection-observer";
// 指示器是否在视图内
const { ref, inView } = useInView();
// 是否在加载下一页
const [isFetchingNextPage, setIsFetchingNextPage] = useState(false);
// 模拟列表数据长度
const [dataLength, setDataLength] = useState(20);
// 是否有下一页,模拟数据最大为60
const hasNextPage = dataLength < 60;
// 模拟请求更多数据
const loadMore = useCallback(() => {
if (
// 指示器出现在视图内
inView &&
// 存在下一页
hasNextPage &&
// 没有在请求中
!isFetchingNextPage
) {
setIsFetchingNextPage(true);
setTimeout(() => {
setDataLength((prev) => prev + 20);
setIsFetchingNextPage(false);
}, 2000);
}
}, [inView, hasNextPage, isFetchingNextPage]);
// 自动加载下一页数据
useEffect(() => {
loadMore();
}, [loadMore]);
<PullToRefreshify
refreshing={refreshing}
onRefresh={handleRefresh}
renderText={renderText}
>
{Array.from({ length: dataLength }).map((item, i) => (
<div key={item.id}>{item}</div>
))}
{/* 加载更多指示器 */}
<button ref={ref} onClick={loadMore}>
{isFetchingNextPage
? "加载更多..."
: hasNextPage
? "点击加载下一页"
: "已经到底了~"}
</button>
</PullToRefreshify>;
在线预览地址
竞品对比
ReactPullToRefreshify | AntDesignMobile PullToRefresh | ReactSimplePullToRefresh | |
---|---|---|---|
下拉百分比动画 | ✅ | 🛑 | 🛑 |
拉动难度 | ✅ | 🛑 | ✅ |
上拉加载 | 🛑 | 🛑 | ✅ |
打包体积 | 2.07kb | 188kb | 2.42kb |
Github
如果你想要了解更多有关实现的信息,请点击下面的链接查看