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><InfiniteScrollclassName={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 // 项目idamount: number // 数量citrineAmount: number // 花费
}class RecordStore {scrollKey = 'init1' // InfiniteScroll key1scrollKey2 = 'init2'    // InfiniteScroll key2selectedMonth = '' // 选中月份monthList: Array<string> = [] // 月份列表totalAmount: number // 总额度1totalAmount2: number // 总额度2dataList: Array<IData> = [] // 数据列表1page = 0 // 当前页码1hasMore = true // 有无下一页信息1dataList2: Array<IData> = [] // 数据列表2page2 = 0 // 当前页码2hasMore2 = true // 有无下一页信息2constructor() {makeAutoObservable(this)}// 更改选中月份async setSelectedMonth(month = '') {runInAction(() => {this.selectedMonth = month})}// 获取月份列表async getMonthList() {const res = await listMonth()if (res.status === 0) {runInAction(() => {this.monthList = res.datathis.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 = 1this.hasMore = true})} else {runInAction(() => {this.scrollKey2 = Math.random().toString(36).substr(2)this.page2 = 1this.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.totalAmountthis.dataList = res.data.datasif ((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.totalAmountthis.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.totalAmountthis.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.totalAmountthis.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: none;border-radius: 0;box-sizing: border-box;z-index: 1;.item {line-height: 20px;padding-left: 18px;background: #eeeeee;height: 24px;&:hover {background: #cccccc;}}}.hide {display: none;}}}}
}.table {width: 416px;margin: 18px 0 0 12px;font-size: 12px;.thead {display: flex;align-items: center;height: 30px;margin-bottom: 4px;background: #f7f3ff;font-weight: bold;}.tbody{height: 330px;}//  react-infinite-scroll-component.row {display: flex;align-items: center;height: 30px;width: 100%;.nickname{width: 90px;@include text-overflow()}}.thead p,.row p {display: inline-block;text-align: center;&:nth-child(1) {width: 88px;}&:nth-child(2) {width: 96px;}&:nth-child(3) {width: 77px;}&:nth-child(4) {width: 70px;}&:nth-child(5) {width: 81px;}}}//  react-infinite-scroll-component
// 滚动条样式
*::-webkit-scrollbar {width: 12px;height: 12px;
}
*::-webkit-scrollbar-button {width: 0px;height: 0px;display: none;
}
*::-webkit-scrollbar-corner {background-color: transparent;
}
*::-webkit-scrollbar-thumb {border: 4px solid rgba(0, 0, 0, 0);height: 6px;border-radius: 25px;background-clip: padding-box;background-color: #eeeeee;
}

补充

react-infinite-scroll-component 是一款滚动加载插件,在页面滚动的时候加载数据。

在页面滚动的时候,infiniteScroll 页面数是自动+1。举个例子,页面加载到第三页,infiniteScroll 无法在重新开始计数,而在某些场景中需要重新开始计数,比如上文中提到的切换月份,page number 需要重新计数。

解决方案: 改变 infiniteScroll 的 key


具体细节实现见以下博客:

  1. 【CSS】自定义下拉框
  2. 【CSS】自定义滚动条样式

【React】react-infinite-scroll-component 实现滚动加载相关推荐

  1. react 实现滚动加载_在React中实现平滑滚动

    react 实现滚动加载 Smooth Scrolling, dont know what it is? Well, instead of clicking on a button and being ...

  2. 如何在React Native中创建精美的动画加载器

    by Vikrant Negi 通过Vikrant Negi 如何在React Native中创建精美的动画加载器 (How to create a beautifully animated load ...

  3. react 中使用import()实现按需加载报错 解决方法 --‘import’ and ‘export’ may only appear at the top level

    react 中使用import()实现按需加载报错 解决方法 --'import' and 'export' may only appear at the top level 参考文章: (1)rea ...

  4. 使用infinite-scroll实现Ghost博文列表的滚动加载

    Ghost博客系统默认提供的博文列表为传统的翻页方式(通过点击上一页.下一页等按钮来切换),随着移动客户端的发展,瀑布流式的滚动加载方式得到广泛应用,有效地提高了用户浏览信息的流畅度.下面详述如何通过 ...

  5. jquery-weui滚动加载问题解决

    2017年12月25日 jquery-weui滚动加载报错问题解决 监听事件 infinite(),下面是源码,infinite(distance)接收distance参数,默认的 distance ...

  6. php 无限滚动加载,无限滚动,_无限滚动加载数据问题,无限滚动 - phpStudy

    无限滚动加载数据问题 做移动端程序的时候,经常会遇到无限滚动的功能,通常实现无限滚动的方式是页面滚动到底部后出发一个ajax请求,后端返回数据然后动态追加DOM,但是如果DOM结构很复杂,追加的时候拼 ...

  7. vue 滑动加载列表 php,通过原生vue添加滚动加载更多功能

    这篇文章主要介绍了通过原生vue添加滚动加载更多功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 vue中添加滚动加载更多,因为是单页面所以需要在 ...

  8. ajax文字上下滚动,ajax页面底部 滚动加载效果 实例

    html部分: //ajax读取的 data.html 使用append 的方式添加到这里 //ajax 状态文字输出到这里 [数据加载中][数据加载成功][没有数据了] js代码需要jquery支持 ...

  9. vue2.0无限滚动加载数据插件

      做vue项目用到下拉滚动加载数据功能,由于选的UI库(element)没有这个组件,就用Vue-infinite-loading 这个插件代替,使用中遇到的一些问题及使用方法,总结作记录! 安装: ...

最新文章

  1. 如果学习编程可以重来
  2. 关于时间类型数据的转换
  3. 解决J2EE系统应用性能问题常用方法
  4. 确保线程安全下使用Queue的Enqueue和Dequeue
  5. php++isfile,PHP DirectoryIterator isFile()用法及代码示例
  6. Kubelet 对资源紧缺状况的应对
  7. Docker在测试领域的应用
  8. CodeCombat 落地马来西亚巴生中华小学,支持人工智能远程教学
  9. 调研分析-全球与中国非线性光学BIBO晶体(BiB3O6)市场现状及未来发展趋势
  10. 轻量级高并发物联网服务器接收程序源码
  11. 32位matlab下载,matlab2008a的32位版本(2G)下载问题及精简安装
  12. php阴阳万年历转换的接口,阴历阳历转换(阴阳转换万年历查询表)
  13. Ubuntu虚拟机安装
  14. leetcode题解日练--2016.8.29
  15. Oracle SQL 批量修改资料库邮箱后缀名称
  16. c++正则表达式regex
  17. Element-UI源码学习——弹框组件
  18. 阿里云ECS服务器跨账号迁移
  19. 智慧物联下主机加固安全解决方案分析
  20. 世界上第一台模拟电子计算机,研发世界第一台电脑的核心人物,被美国隐藏35年,只因他是个华人...

热门文章

  1. 计算机行业不是本科真的难进吗,本科最难就业的的专业都有哪些?你的专业位列其中吗?...
  2. 第一篇 如何选择深度学习主机
  3. 2022世界杯在哪个国家举办,具体日期
  4. 关于Qt中的Q_D,Q_Q
  5. 【React】717- 从零实现 React-Redux
  6. SSM框架之酒店管理系统三(菜单数据库设计,菜单列表查询渲染)
  7. linux面试宝典 pdf,运维工程师面试题(面试版).pdf
  8. C++常用函数--stoi函数用法总结
  9. Docker安装及若干问题解析
  10. xcodebuild命令的使用