移动端的下拉刷新和上滑加载
本文叙述了在mobile端实现下拉刷新和上拉加载的经典功能。功能是通过antd-mobile组件实现的,欢迎大家在评论区提出意见,谢谢!
1. 下拉刷新
PullToRefresh
组件是 Ant Design Mobile V2(antd-mobile-v2)中用于下拉刷新的组件。它提供了一种用户友好的方式来触发数据的更新,通常用于移动端应用的列表页面。
API 和原理:
API
- onRefresh (function): 在下拉刷新时触发的回调函数。
- direction (string): 指定下拉刷新的方向,可以是
down
(默认)或up
。 - indicator (object): 自定义提示文案的配置。
- distanceToRefresh (number): 触发刷新的距离,默认为
50px
。 - damping (number): 阻尼系数,值越大表示阻尼越小,可以通过调整这个值改变下拉刷新的感觉。
- getScrollContainer (function): 获取滚动容器的函数,用于指定滚动的容器,默认为 window。
- prefixCls (string): 样式类名的前缀。
原理
PullToRefresh
主要通过监听用户的下拉手势,当下拉的距离达到一定值时,触发刷新操作。同时,在刷新过程中,会显示相应的提示文案或图标,提供良好的用户体验。
使用示例:
import React, { useState, useEffect } from 'react';
import { PullToRefresh, ListView } from 'antd-mobile-v2';
const MyList = () => {
const [dataSource, setDataSource] = useState(new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}));
const [refreshing, setRefreshing] = useState(false);
const onRefresh = () => {
// 模拟异步数据加载
setRefreshing(true);
fetchData().then(() => {
setRefreshing(false);
});
};
useEffect(() => {
// 初始化数据
fetchData();
}, []);
const fetchData = async () => {
// 模拟异步数据加载
const data = await fetchDataFromAPI();
setDataSource(dataSource.cloneWithRows(data));
};
const renderRow = (rowData, sectionID, rowID) => (
<div key={rowID}>{rowData}</div>
);
return (
<ListView
dataSource={dataSource}
renderRow={renderRow}
renderFooter={() => <div>Loading...</div>}
renderHeader={() => (
<PullToRefresh
onRefresh={onRefresh}
distanceToRefresh={50}
refreshing={refreshing}
/>
)}
/>
);
};
export default MyList;
详细解释
逐步解释这段代码:
1. 导入语句:
import React, { useState, useEffect } from 'react';
import { PullToRefresh, ListView } from 'antd-mobile-v2';
解释:从 'antd-mobile-v2' 库和 React 中导入必要的组件。导入的组件包括 PullToRefresh
和 ListView
。
2. 函数组件声明:
const MyList = () => {
// 状态钩子
const [dataSource, setDataSource] = useState(new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}));
const [refreshing, setRefreshing] = useState(false);
解释:声明一个名为 MyList
的函数组件。使用 useState
钩子来管理组件的状态。定义了两个状态变量:dataSource
用于管理 ListView
的数据源,refreshing
用于追踪刷新状态。
3. onRefresh 函数:
const onRefresh = () => {
// 模拟异步数据加载
setRefreshing(true);
fetchData().then(() => {
setRefreshing(false);
});
};
解释:定义 onRefresh
函数,模拟异步数据加载过程。将 refreshing
状态设置为 true
,调用 fetchData
函数,然后一旦数据获取完成,将 refreshing
设置回 false
。
4. 用于初始数据获取的 useEffect:
useEffect(() => {
// 初始化数据
fetchData();
}, []);
解释:使用 useEffect
钩子在组件挂载时执行初始数据获取。通过调用 fetchData
函数,使用空依赖数组确保它在组件初始化时只运行一次。
5. fetchData 函数:
const fetchData = async () => {
// 模拟异步数据加载
const data = await fetchDataFromAPI();
setDataSource(dataSource.cloneWithRows(data));
};
解释:定义 fetchData
函数,负责从 API(这里是模拟的)获取数据。使用 await
处理异步调用,通过使用新获取的数据克隆更新 dataSource
状态。
6. renderRow 函数:
const renderRow = (rowData, sectionID, rowID) => (
<div key={rowID}>{rowData}</div>
);
解释:定义 renderRow
函数,负责渲染 ListView
中的每一行。接收 rowData
、sectionID
和 rowID
,返回一个带有 rowData
内容的 div
元素。
7. 返回 JSX 结构:
return (
<ListView
dataSource={dataSource}
renderRow={renderRow}
renderFooter={() => <div>Loading...</div>}
renderHeader={() => (
<PullToRefresh
onRefresh={onRefresh}
distanceToRefresh={50}
refreshing={refreshing}
/>
)}
/>
);
};
解释:组件的主要渲染部分。返回一个具有指定属性的 ListView
组件,包括 dataSource
、renderRow
、renderFooter
和 renderHeader
。renderHeader
包含一个 PullToRefresh
组件,在下拉时触发 onRefresh
函数。
8. 导出组件:
export default MyList;
解释:导出 MyList
组件,以便在应用程序的其他部分中使用。
2. 上滑加载
若您想同时实现下拉刷新和上滑加载,可以结合 ListView
提供的 onEndReached
回调和 renderFooter
来实现上滑加载的效果。以下是一个基本的实现示例:
import React, { useState, useEffect } from 'react';
import { PullToRefresh, ListView } from 'antd-mobile-v2';
const MyList = () => {
const [dataSource, setDataSource] = useState(new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}));
const [refreshing, setRefreshing] = useState(false);
const [isLoadingMore, setIsLoadingMore] = useState(false);
const onRefresh = () => {
// 模拟异步数据加载
setRefreshing(true);
fetchData().then(() => {
setRefreshing(false);
});
};
const onEndReached = () => {
// 防止重复触发
if (!isLoadingMore) {
setIsLoadingMore(true);
// 模拟异步加载更多数据
fetchMoreData().then(() => {
setIsLoadingMore(false);
});
}
};
useEffect(() => {
// 初始化数据
fetchData();
}, []);
const fetchData = async () => {
// 模拟异步数据加载
const data = await fetchDataFromAPI();
setDataSource(dataSource.cloneWithRows(data));
};
const fetchMoreData = async () => {
// 模拟异步加载更多数据
const moreData = await fetchMoreDataFromAPI();
setDataSource(dataSource.cloneWithRows([...dataSource._dataBlob.s1, ...moreData]));
};
const renderRow = (rowData, sectionID, rowID) => (
<div key={rowID}>{rowData}</div>
);
const renderFooter = () => (
<div style={{ padding: 30, textAlign: 'center' }}>
{isLoadingMore ? 'Loading more...' : ''}
</div>
);
return (
<ListView
dataSource={dataSource}
renderRow={renderRow}
renderFooter={renderFooter}
renderHeader={() => (
<PullToRefresh
onRefresh={onRefresh}
distanceToRefresh={50}
refreshing={refreshing}
/>
)}
onEndReached={onEndReached}
onEndReachedThreshold={10}
/>
);
};
export default MyList;
详细解释
继续解释这段代码:
1. 新增状态钩子:
const [isLoadingMore, setIsLoadingMore] = useState(false);
解释:新增了一个状态变量 isLoadingMore
,用于追踪是否正在加载更多数据。
2. onEndReached 函数:
const onEndReached = () => {
// 防止重复触发
if (!isLoadingMore) {
setIsLoadingMore(true);
// 模拟异步加载更多数据
fetchMoreData().then(() => {
setIsLoadingMore(false);
});
}
};
解释:定义 onEndReached
函数,用于在列表滚动到底部时加载更多数据。通过检查 isLoadingMore
变量,防止重复触发加载更多。
3. fetchMoreData 函数:
const fetchMoreData = async () => {
// 模拟异步加载更多数据
const moreData = await fetchMoreDataFromAPI();
setDataSource(dataSource.cloneWithRows([...dataSource._dataBlob.s1, ...moreData]));
};
解释:定义 fetchMoreData
函数,模拟异步加载更多数据。将新获取的数据与当前数据合并,并通过 cloneWithRows
更新 dataSource
。
4. renderFooter 函数:
const renderFooter = () => (
<div style={{ padding: 30, textAlign: 'center' }}>
{isLoadingMore ? 'Loading more...' : ''}
</div>
);
解释:定义 renderFooter
函数,用于渲染列表底部。根据 isLoadingMore
变量的值,显示加载更多的提示信息。
5. 返回 JSX 结构:
return (
<ListView
dataSource={dataSource}
renderRow={renderRow}
renderFooter={renderFooter}
renderHeader={() => (
<PullToRefresh
onRefresh={onRefresh}
distanceToRefresh={50}
refreshing={refreshing}
/>
)}
onEndReached={onEndReached}
onEndReachedThreshold={10}
/>
);
};
解释:在 ListView
中添加了 onEndReached
和 onEndReachedThreshold
属性,用于触发加载更多数据的逻辑。renderFooter
用于显示底部加载更多的提示信息。整个组件现在支持上拉加载更多的功能。
转载自:https://juejin.cn/post/7331654094375649289