Reactreact-infinite-scroll-component 实现滚动加载
Posted 嘻嘻的妙妙屋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Reactreact-infinite-scroll-component 实现滚动加载相关的知识,希望对你有一定的参考价值。
react-infinite-scroll-component 实现滚动加载
效果
index.tsx
import useState, useEffect from 'react'
import observer from 'mobx-react-lite'
import styles from './index.module.scss'
import recordStore, IData from 'src/store/recordStore'
import formatTimestamp from 'src/utils'
import InfiniteScroll from 'react-infinite-scroll-component'
const TableContent: React.FC = props =>
// 查询月份下拉框
const [dropDown, setDropDown] = useState(false)
const handleOpen = (e: any) =>
e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()
setDropDown(!dropDown)
useEffect(() =>
document.body.addEventListener('click', () =>
setDropDown(false)
)
return () =>
document.body.removeEventListener('click', () =>
setDropDown(false)
)
, [])
const selectMonth = (e: any) =>
// console.log(e.currentTarget.getAttribute('data-name'))
setDropDown(!dropDown)
const month = e.currentTarget.getAttribute('data-name')
recordStore.setSelectedMonth(month)
// 获取最近月份记录
useEffect(() =>
if (recordStore.selectedMonth)
recordStore.fetchMonthlyData()
, [recordStore.selectedMonth])
return (
<div className=styles.container>
<div className=styles.title>
<div className=styles.sum>合计:recordStore.totalAmount</div>
<div className=styles.search>
查询
<div className=styles.select>
<ul>
<li>
<div className=styles.head onClick=handleOpen>
<span>recordStore.selectedMonth</span>
<span className=styles.icon_down></span>
</div>
<ul className=dropDown ? styles.option : styles.hide>
recordStore.monthList &&
recordStore.monthList.map((item: string, index: number) => (
<li key=`month_$index` data-name=item className=styles.item onClick=selectMonth>
item
</li>
))
</ul>
</li>
</ul>
</div>
</div>
</div>
<div className=styles.table>
<div className=styles.thead>
<p>时间</p>
<p>昵称</p>
<p>项目</p>
<p>数量</p>
<p>花费</p>
</div>
<InfiniteScroll
className=styles.scroll
dataLength=recordStore.dataList.length
next=() =>
recordStore.fetchDataList()
hasMore=recordStore.hasMore
height=320
key=recordStore.scrollKey
>
<div className=styles.tbody>
recordStore.dataList &&
recordStore.dataList.map((item: IData, index: number) => (
<div key=`data_tab1_$index` className=styles.row>
<p>formatTimestamp(item.createTime)</p>
<p className=styles.nickname>item.nickname</p>
<p>item.itemName</p>
<p>item.amount</p>
<p>item.citrineAmount</p>
</div>
))
!recordStore.dataList && (
<div style=textAlign: 'center', lineHeight: '200px', color: 'rgba(0,0,0,0.3)'>暂无数据</div>
)
</div>
</InfiniteScroll>
</div>
</div>
)
export default observer(TableContent)
recordStore.ts
import makeAutoObservable, runInAction from 'mobx'
import formatMonth from 'src/utils'
import getDataList, listMonth from 'src/services/api'
export interface IData
nickname: string // 昵称
createTime: number // 时间
itemName: string // 项目名称
itemId: number // 项目id
amount: number // 数量
citrineAmount: number // 花费
class RecordStore
scrollKey = 'init1' // InfiniteScroll key1
scrollKey2 = 'init2' // InfiniteScroll key2
selectedMonth = '' // 选中月份
monthList: Array<string> = [] // 月份列表
totalAmount: number // 总额度1
totalAmount2: number // 总额度2
dataList: Array<IData> = [] // 数据列表1
page = 0 // 当前页码1
hasMore = true // 有无下一页信息1
dataList2: Array<IData> = [] // 数据列表2
page2 = 0 // 当前页码2
hasMore2 = true // 有无下一页信息2
constructor()
makeAutoObservable(this)
// 更改选中月份
async setSelectedMonth(month = '')
runInAction(() =>
this.selectedMonth = month
)
// 获取月份列表
async getMonthList()
const res = await listMonth()
if (res.status === 0)
runInAction(() =>
this.monthList = res.data
this.selectedMonth = res.data.length > 0 && res.data[0]
)
// 获取月份记录
async fetchMonthlyData(tab = 1, size = 11)
if (tab === 1)
runInAction(() =>
this.scrollKey = Math.random().toString(36).substr(2)
this.page = 1
this.hasMore = true
)
else
runInAction(() =>
this.scrollKey2 = Math.random().toString(36).substr(2)
this.page2 = 1
this.hasMore = true
)
// ↓↓↓↓↓↓↓↓↓↓-测试数据-↓↓↓↓↓↓↓↓↓↓
const item =
yyno: 1,
nickname: '昵称昵称',
createTime: 1655275863,
itemName: '金拱门',
itemId: 1,
amount: 100,
citrineAmount: 1000,
const d: any = []
for (let i = 0; i < 11; i++)
d.push(item)
// ↑↑↑↑↑↑↑↑↑↑-测试数据-↑↑↑↑↑↑↑↑↑↑
const res = await getDataList(
tab: tab,
month: formatMonth(this.selectedMonth),
size: size,
page: tab === 1 ? this.page : this.page2,
)
if (res.status === 0)
if (tab === 1)
runInAction(() =>
// ↓↓↓↓↓↓↓↓↓↓-测试数据-↓↓↓↓↓↓↓↓↓↓
res.data.datas = d
// ↑↑↑↑↑↑↑↑↑↑-测试数据-↑↑↑↑↑↑↑↑↑↑
this.totalAmount = res.data.totalAmount
this.dataList = res.data.datas
if ((this.dataList && this.dataList.length < size) || !this.dataList)
this.hasMore = false
// ↓↓↓↓↓↓↓↓↓↓-测试数据加载完毕-↓↓↓↓↓↓↓↓↓↓
if (!this.dataList || (this.dataList && this.dataList.length > 100))
this.hasMore = false
// ↑↑↑↑↑↑↑↑↑↑-测试数据加载完毕-↑↑↑↑↑↑↑↑↑↑
)
else
runInAction(() =>
this.totalAmount2 = res.data.totalAmount
this.dataList2 = res.data.datas && this.dataList2.concat(...res.data.datas)
if ((this.dataList2&& this.dataList2.length < size) || !this.dataList2)
this.hasMore2 = false
)
// 分页获取帮扶/被帮扶记录
async fetchDataList(tab = 1, size = 11)
if (tab === 1)
runInAction(() =>
this.page++
)
else
runInAction(() =>
this.page2++
)
// ↓↓↓↓↓↓↓↓↓↓-测试数据-↓↓↓↓↓↓↓↓↓↓
const item =
nickname: '我的昵称',
createTime: 1655275863,
itemName: '麦当当',
itemId: 1,
amount: 100,
citrineAmount: 1000,
const d: any = []
for (let i = 0; i < 11; i++)
d.push(item)
// ↑↑↑↑↑↑↑↑↑↑-测试数据-↑↑↑↑↑↑↑↑↑↑
const res = await getDataList(
tab: tab,
month: formatMonth(this.selectedMonth),
size: size,
page: tab === 1 ? this.page : this.page2,
)
if (res.status === 0)
if (tab === 1)
runInAction(() =>
// ↓↓↓↓↓↓↓↓↓↓-测试数据-↓↓↓↓↓↓↓↓↓↓
res.data.datas = d
// ↑↑↑↑↑↑↑↑↑↑-测试数据-↑↑↑↑↑↑↑↑↑↑
this.totalAmount = res.data.totalAmount
this.dataList = res.data.datas && this.dataList.concat(...res.data.datas)
if ((this.dataList && this.dataList.length < size) || !this.dataList)
this.hasMore = false
// ↓↓↓↓↓↓↓↓↓↓-测试数据加载完毕-↓↓↓↓↓↓↓↓↓↓
if (!this.dataList || (this.dataList && this.dataList.length > 100))
this.hasMore = false
// ↑↑↑↑↑↑↑↑↑↑-测试数据加载完毕-↑↑↑↑↑↑↑↑↑↑
)
else
runInAction(() =>
this.totalAmount2 = res.data.totalAmount
this.dataList2 = res.data.datas && this.dataList2.concat(...res.data.datas)
if ((this.dataList2 && this.dataList2.length < size) || !this.dataList2)
this.hasMore2 = false
)
export default new RecordStore()
index.module.scss
li
list-style: none;
.title
display: flex;
justify-content: space-between;
align-items: center;
width: 416px;
margin: 18px 12px 0;
padding: 0 18px 0 22px;
font-size: 12px;
.sum
color: #ff6600;
.search
display: flex;
line-height: 24px;
ul
margin-left: 8px;
width: 96px;
height: 24px;
border: 1px solid #dcdcdc;
border-radius: 5px;
background: #eeeeee;
font-size: 12px;
cursor: pointer;
li
position: relative;
.head
overflow: hidden;
width: 100%;
height: 24px;
box-sizing: border-box;
line-height: 20px;
padding-left: 15px;
.icon_down
position: absolute;
top: 8px;
right: 16px;
width: 11px;
height: 7px;
background-image: url(../imgs/icon_down.png);
background-size: 100%;
.option
width: 96px;
position: absolute;
top: 23px;
left: -9px;
border以上是关于Reactreact-infinite-scroll-component 实现滚动加载的主要内容,如果未能解决你的问题,请参考以下文章