0803分页_加载更多-网络ajax请求2-react-仿低代码平台项目

文章目录

    • 1 分页
      • 1.1 url与分页参数
      • 1.2 分页组件与url
      • 1.3 列表页引用分页组件
    • 2 加载更多
      • 2.1 状态
      • 2.2 触发时机
      • 2.3 加载数据
      • 2.4优化
    • 结语

1 分页

1.1 url与分页参数

查询问卷列表接口,添加分页参数:

  • page:当前页码(第几页)
  • pageSize:每页多少条记录

question.ts 查询文件接口列表参数扩展,如下所示:

type SearchOption = {keyword: string;isStar: boolean;isDeleted: boolean;page: number;pageSize: number;
};

浏览器url获取分页参数,useLoadQuestionListData.ts代码如下所示:

import { useSearchParams } from "react-router-dom";
import { useRequest } from "ahooks";
import { getQuestionListApi } from "@/api/question";import {LIST_SEARCH_PARAM_KEY,LIST_PAGE_PARAM_KEY,LIST_PAGE_SIZE_PARAM_KEY,LIST_PAGE_SIZE_DEFAULT,LIST_PAGE_DEFAULT,
} from "@/constant";type OptionType = {isStar: boolean;isDeleted: boolean;page: number;pageSize: number;
};/*** 获取问卷列表* @returns 问卷列表*/
function useLoadQuestionListData(opt: Partial<OptionType>) {const { isStar, isDeleted } = opt;const [searchParams] = useSearchParams();const keyword = searchParams.get(LIST_SEARCH_PARAM_KEY) || "";const page =parseInt(searchParams.get(LIST_PAGE_PARAM_KEY) || "") || LIST_PAGE_DEFAULT ;const pageSize =parseInt(searchParams.get(LIST_PAGE_SIZE_PARAM_KEY) || "") ||LIST_PAGE_SIZE_DEFAULT;async function load() {const data = await getQuestionListApi({keyword,isStar,isDeleted,page,pageSize,});//...
}export default useLoadQuestionListData;

服务端解析分页参数,question.js代码如下:

const Mock = require('mockjs')const getQuestionList = require("./data/getQuestionList")const Random = Mock.Randommodule.exports = [// ...{// 获取问卷列表url: '/api/question',method: 'get',response(ctx) {const { query = {} } = ctxconst isStar = query.isStar === 'true'const isDeleted = query.isDeleted === 'true'const page = parseInt(query.page) || 1const pageSize = parseInt(query.pageSize) || 10return {errno: 0,data: {list: getQuestionList({isStar, isDeleted, page, pageSize}),total: 100}}}},
]

1.2 分页组件与url

antd分页组件与url交互

由于多个列表页面都需要分页组件,这里我们以antd分页组件为基础,封装自定义分页组件,并且实现分页参数与url参数交互,ListPage.tsx代码如下所示:

import { FC, useEffect, useState } from "react";
import { useLocation, useNavigate, useSearchParams } from "react-router-dom";
import { Pagination } from "antd";import {LIST_PAGE_DEFAULT,LIST_PAGE_PARAM_KEY,LIST_PAGE_SIZE_DEFAULT,LIST_PAGE_SIZE_PARAM_KEY,
} from "@/constant";type PropsType = {total: number;
};const ListPage: FC<PropsType> = (props: PropsType) => {const [current, setCurrent] = useState(LIST_PAGE_DEFAULT);const [pageSize, setPageSize] = useState(LIST_PAGE_SIZE_DEFAULT);const [searchParams] = useSearchParams();useEffect(() => {const curPage =parseInt(searchParams.get(LIST_PAGE_PARAM_KEY) || "") ||LIST_PAGE_DEFAULT;const curPageSize =parseInt(searchParams.get(LIST_PAGE_SIZE_PARAM_KEY) || "") ||LIST_PAGE_SIZE_DEFAULT;setCurrent(curPage);setPageSize(curPageSize);}, [searchParams]);const { total } = props;// 当page pageSize改变时,跳转页面(改变url)const nav = useNavigate();const { pathname } = useLocation();function handlePageChange(page: number, pageSize: number) {searchParams.set(LIST_PAGE_PARAM_KEY, page.toString());searchParams.set(LIST_PAGE_SIZE_PARAM_KEY, pageSize.toString());nav({pathname,search: searchParams.toString(),});}return (<Paginationcurrent={current}pageSize={pageSize}total={total}onChange={handlePageChange}/>);
};export default ListPage;

1.3 列表页引用分页组件

“星标问卷”列表页Star.tsx代码如下:

// ...
import ListPage from "@/components/ListPage";const List: FC = () => {// ...//问卷列表数据const { data = {}, loading } = useLoadQuestionListData({ isStar: true });const { list = [], total = 0 } = data;
// ...<div className={styles.footer}><ListPage total={total} /></div></>);
};export default List;

“回收站”列表页Trash.tsx代码如下所示:

import { FC, useState } from "react";
import { useTitle } from "ahooks";
import ListPage from "../../components/ListPage";const List: FC = () => {useTitle("调查问卷-回收站");//问卷列表数据const { data = {}, loading } = useLoadQuestionListData({ isDeleted: true });const { list = [], total = 0 } = data;
// ...<div className={styles.footer}><ListPage total={total} /></div></>);
};export default List;

在这里插入图片描述

2 加载更多

2.1 状态

基础

  • page:当前页
  • list:全部数据列表,上划累加
  • total:总条数

计算项

  • hasMoreData:是否有更多数据

2.2 触发时机

  • 页面加载触发
  • 页面滚动到加载更多数据时触发
    • 监听页面滚动
    • 防抖处理
    • DOM计算页面滚动刀”加载更多“

2.3 加载数据

  • useRequest请求接口
  • 接口返回数据,设置状态

2.4优化

  • 加载更多,缓存处理
  • 刷新页面优化暂无数据
  • 搜索重置状态

完整”我的问卷“页List.tsx代码如下所示:

import { FC, useEffect, useMemo, useRef, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { useDebounceFn, useRequest, useTitle } from "ahooks";
import { Typography, Spin, Empty } from "antd";import QuestionCard from "@/components/QuestionCard";
import ListSearch from "@/components/ListSearch";
import styles from "./common.module.scss";
import { getQuestionListApi } from "@/api/question";
import { LIST_PAGE_SIZE_DEFAULT, LIST_SEARCH_PARAM_KEY } from "@/constant";const { Title } = Typography;const List: FC = () => {useTitle("调查问卷-我的问卷");//问卷列表数据const [started, setStarted] = useState(false);const [page, setPage] = useState(1);const [list, setList] = useState([]); // 全部列表数据,上划加载更多,累计const [total, setTotal] = useState(0);const hasMoreData = total > list.length;const [searchParams] = useSearchParams();const keyword = searchParams.get(LIST_SEARCH_PARAM_KEY) || "";// 搜索重置状态useEffect(() => {setStarted(false);setPage(1);setList([]);setTotal(0);}, [keyword]);// 加载数据const { run: loadData, loading } = useRequest(async () => {const data = await getQuestionListApi({page,pageSize: LIST_PAGE_SIZE_DEFAULT,keyword,});return data;},{manual: true,onSuccess(res) {const { list: newList = [], total = 0 } = res;// 累计数据setList(list.concat(newList));setTotal(total);setPage(page + 1);},});// 尝试触发加载-防抖处理const containerRef = useRef<HTMLDivElement>(null);const { run: tryLoadMore } = useDebounceFn(() => {const elem = containerRef.current;if (elem == null) {return;}// 判断如果div bottom 小于等于页面的高度const domRect = elem.getBoundingClientRect();if (domRect == null) {return;}const { bottom } = domRect;if (bottom <= document.body.clientHeight) {// 加载数据loadData();setStarted(true);}},{ wait: 500 });// 触发时机:页面加载或者url参数(keyword)变化时useEffect(() => {// 第一次加载,初始化tryLoadMore();}, [searchParams]);// 监听页面滚动事件useEffect(() => {if (hasMoreData) {window.addEventListener("scroll", tryLoadMore);}return () => {// 解绑事件window.removeEventListener("scroll", tryLoadMore);};}, [searchParams, hasMoreData]);// 加载更多显示优化const LoadMoreContentElem = useMemo(() => {if (!started || loading) {return <Spin />;}if (total === 0) {return <Empty description="暂无数据" />;}if (!hasMoreData) {return <span>没有更多了……</span>;}return <span>开始加载下一页</span>;}, [started, loading, hasMoreData]);return (<><div className={styles.header}><div className={styles.left}><Title level={3}>我的问卷</Title></div><div className={styles.right}><ListSearch /></div></div><div className={styles.content}>{list.length > 0 &&list.map((q: any) => {const { _id } = q;return <QuestionCard key={_id} {...q} />;})}</div><div className={styles.footer}><div ref={containerRef}>{LoadMoreContentElem}</div></div></>);
};export default List;

在这里插入图片描述

结语

❓QQ:806797785

⭐️仓库地址:https://gitee.com/gaogzhen

⭐️仓库地址:https://github.com/gaogzhen

[1]ahook官网[CP/OL].

[2]mock文档[CP/OL].

[3]Ant Design官网[CP/OL].

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/903172.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【技术追踪】基于扩散模型的脑图像反事实生成与异常检测(TMI-2024)

一种新颖的扩散模型双重采样策略&#xff0c;DDPM DDIM ~ 论文&#xff1a;Diffusion Models for Counterfactual Generation and Anomaly Detection in Brain Images 0、摘要 病理区域的分割掩模在许多医学应用中很有用&#xff0c;例如脑肿瘤和中风管理。此外&#xff0c;疾…

第十六届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学 A 组

比赛还没有开始&#xff0c;竟然忘记写using namespace std; //debug半天没看明白 (平时cv多了 然后就是忘记那个编译参数&#xff0c;&#xff08;好惨的开局 编译参数-stdc11 以下都是赛时所写代码&#xff0c;赛时无聊时把思路都打上去了&#xff08;除了倒数第二题&#…

CentOS 7上Memcached的安装、配置及高可用架构搭建

Memcached是一款高性能的分布式内存缓存系统&#xff0c;常用于加速动态Web应用的响应。本文将在CentOS 7上详细介绍Memcached的安装、配置&#xff0c;以及如何实现Memcached的高可用架构。 &#xff08;1&#xff09;、搭建memcached 主主复制架构 Memcached 的复制功能支持…

告别进度失控:用燃尽图补上甘特图的监控盲区

在职场中&#xff0c;项目经理最头疼的莫过于“计划赶不上变化”。明明用甘特图排好了时间表&#xff0c;任务却总像脱缰野马——要么进度滞后&#xff0c;要么资源分配失衡。甘特图虽能直观展示任务时间轴&#xff0c;但面对突发风险或团队效率波动时&#xff0c;它更像一张“…

爬虫-oiwiki

我们将BASE_URL 设置为 "https://oi-wiki.org/" 后脚本就会自动开始抓取该url及其子页面的所有内容&#xff0c;并将统一子页面的放在一个文件夹中 import requests from bs4 import BeautifulSoup from urllib.parse import urljoin, urlparse import os import pd…

业务中台与数据中台:企业数字化转型的核心引擎

前言&#xff1a;在当今数字化浪潮下&#xff0c;企业为了提升运营效率、加速创新步伐并更好地适应市场变化&#xff0c;业务中台与数据中台应运而生&#xff0c;成为企业架构中的关键组成部分。本文将深入探讨业务中台和数据中台的简介、发展史、技术流环节以及在实际生产中的…

django admin 去掉新增 删除

在Django Admin中&#xff0c;你可以通过自定义Admin类来自定义哪些按钮显示&#xff0c;哪些不显示。如果你想隐藏“新增”和“删除”按钮&#xff0c;可以通过重写change_list_template或使用ModelAdmin的has_add_permission和has_delete_permission属性来实现。 方法1&…

基于云原生架构的后端微服务治理实战指南

一、引言&#xff1a;为什么在云原生时代更需要微服务治理&#xff1f; 在单体应用时代&#xff0c;开发和部署虽然简单&#xff0c;但随着系统规模的扩大&#xff0c;单体架构的维护成本急剧上升&#xff0c;部署频率受限&#xff0c;模块之间相互影响&#xff0c;最终导致系…

MIT6.S081 - Lab10 mmap(文件内存映射)

本篇是 MIT6.S081 2020 操作系统课程 Lab10 的实验笔记&#xff0c;目标只有一个&#xff1a;实现文件映射到内存的功能&#xff0c;也就是 mmap。 作为一名 Android 开发者&#xff0c;我可太熟悉 mmap 这个词儿了。Android 的 跨进程通信 Binder 驱动、图形内存分配和管理、…

基于BenchmarkSQL的OceanBase数据库tpcc性能测试

基于BenchmarkSQL的OceanBase数据库tpcc性能测试 安装BenchmarkSQL及其依赖安装软件依赖编译BenchmarkSQLBenchmarkSQL props文件配置数据库和测试表配置BenchmarkSQL压测装载测试数据TPC-C压测(固定事务数量)TPC-C压测(固定时长)生成测试报告重复测试流程梳理安装Benchmar…

WinForm真入门(17)——NumericUpDown控件详解

一、基本概念‌ NumericUpDown 是 Windows 窗体中用于数值输入的控件&#xff0c;由文本框和上下调节按钮组成。用户可通过以下方式调整数值&#xff1a; 点击调节按钮增减数值键盘直接输入使用方向键调整 适用于需要限制数值范围或精确控制的场景&#xff08;如年龄、参数配…

汽车自动驾驶介绍

0 Preface/Foreword 1 介绍 1.1 FSD FSD: Full Self-Driving&#xff0c;完全自动驾驶 &#xff08;Tesla&#xff09; 1.2 自动驾驶级别 L0 - L2&#xff1a;辅助驾驶L3&#xff1a;有条件自动驾驶L4/5 &#xff1a;高度/完全自动驾驶

AiCube 试用 - ADC 水位监测系统

AiCube 试用 - ADC 水位监测系统 水位检测在水资源管理、城市防洪、农业灌溉、家用电器和工业生产等多领域发挥积极建设作用。利用水位传感器&#xff0c;可以实现水资源的智能管理&#xff0c;提高生产效率。 本文介绍了擎天柱开发板利用 AiCube 工具快速创建 I/O 电压读取&…

秒杀压测计划 + Kafka 分区设计参考

文章目录 前言&#x1f680; 秒杀压测计划&#xff08;TPS预估 测试流程&#xff09;1. 目标设定2. 压测工具推荐3. 压测命令示例&#xff08;ab版&#xff09;4. 测试关注指标 &#x1f4e6; Kafka Topic 分区设计参考表1. 单 Topic 设计2. 分区路由规则设计&#xff08;Part…

memcpy 使用指南 (C语言)

memcpy 是 C 语言标准库中的一个重要函数&#xff0c;用于在内存区域之间复制数据。它是 <string.h> 头文件中定义的高效内存操作函数之一。 函数原型 void *memcpy(void *dest, const void *src, size_t n); 参数说明 dest: 目标内存地址&#xff0c;数据将被复制到这…

跨境电商货物体积与泡重计算器:高效便捷的物流计算工具

跨境电商货物体积与泡重计算器&#xff1a;高效便捷的物流计算工具 工具简介 货物体积与泡重计算器是一款免费的在线工具&#xff0c;专门为物流从业者、跨境电商卖家和需要计算货物运输体积重量的用户设计。这款工具可以帮助您快速计算货物的体积和对应的空运、快递泡重&…

如何避免爬虫因Cookie过期导致登录失效

1. Cookie的作用及其过期机制 1.1 什么是Cookie&#xff1f; Cookie是服务器发送到用户浏览器并保存在本地的一小段数据&#xff0c;用于维持用户会话状态。爬虫在模拟登录后&#xff0c;通常需要携带Cookie访问后续页面。 1.2 Cookie为什么会过期&#xff1f; 会话Cookie&…

matlab simulink中理想变压激磁电流容易有直流偏置的原因分析。

simulink把线性变压器模块拉出来&#xff0c;设置没有绕线电阻的变压器&#xff0c;激磁电感和Rm都有&#xff0c;然后给一个50%占空比的方波&#xff0c;幅值正负10V&#xff0c;线路中设置一个电阻&#xff0c;模拟导线阻抗。通过示波器观察激磁电流&#xff0c;发现电阻越小…

电力系统失步解列与振荡解析

一、基本概念解析 1. 失步&#xff08;Out-of-Step&#xff09; 在电力系统中&#xff0c;失步是指并列运行的同步发电机因功率失衡导致转子间相对角度超过稳定极限&#xff0c;无法维持同步运行的状态。具体表现为&#xff1a; 当系统发生短路、负荷突变或故障切除等扰动时&…

ctfhub-RCE

关于管道操作符 windows&#xff1a; 1. “|”&#xff1a;直接执行后面的语句。 2. “||”&#xff1a;如果前面的语句执行失败&#xff0c;则执行后面的语句&#xff0c;前面的语句只能为假才行。 3. “&”&#xff1a;两条命令都执行&#xff0c;如果前面的语句为假则直…