React + 项目(从基础到实战) -- 第九期

embedded/2024/9/24 13:20:31/

实现分页 , LoadMore 上划加载更多功能效果

分页

page : 当前页
pageSize: 页面大小

自定义分页组件

组件传值

在这里插入图片描述

import {FC , useEffect, useState } from 'react'import { useNavigate , useLocation ,useSearchParams} from 'react-router-dom';import { Pagination } from "antd";import {LIST_SEARCH_PARAM_PAGE,LIST_SEARCH_PARAM_SIZE,} from "../constant/index";type PropsType={total:number}const ListPage: FC<PropsType> = (props : PropsType) => {//总条数const {total} = props;//当前页const[page,setPage] = useState(1)const[pageSize , setPageSize] = useState(10) //默认设置10个一页//从url中获取page,pageSize,同步到Pagination组件中const [searchParams] = useSearchParams()useEffect(()=>{const page=parseInt(searchParams.get(LIST_SEARCH_PARAM_PAGE) || '1')setPage(page)const pageSize=parseInt(searchParams.get(LIST_SEARCH_PARAM_SIZE) || '10')setPageSize(pageSize)},[searchParams])//当page,pagesize 改变时 , 触发的函数,跳转页面const nav = useNavigate()const {pathname} = useLocation()const changePage = (page : number ,pageSize : number)=>{searchParams.set(LIST_SEARCH_PARAM_PAGE,page.toString())searchParams.set(LIST_SEARCH_PARAM_SIZE,pageSize.toString())nav({pathname,search:searchParams.toString(),//注意是toSting,之前的keyword也可以保留})}return(<div><Pagination current={page} pageSize={pageSize} total={total} onChange={changePage} />;</div>)}export default ListPage;

LoadMore效果

 //loadMore函数const loadMore = () => {console.log("loadMore");}//1. 当页面刷新,url参数(keyword)改变时触发const [searchParams] = useSearchParams();useEffect(()=>{loadMore()},[searchParams])//2. 滚动页面时触发useEffect(()=>{if(hasMore){window.addEventListener("scroll",loadMore)}//解绑事件!!!!!return ()=>{window.removeEventListener("scroll",loadMore)}})

发现 下滑时多次触发事件

防抖

使用ahooks中的useDebounceFn

 //触发加载 ---- 防抖const {run:loadMore} =useDebounceFn(()=>{console.log("tryLoadMore");},{wait:1000})

发现一滑动就执行loadmore

目标: 底部load出现在页面中,就执行loadMore

dom操作
useRef

<div ref={contanerRef}>loadMore ....</div>//触发加载 ---- 防抖const contanerRef = useRef<HTMLDivElement>(null)const {run:loadMore} =useDebounceFn(()=>{const elem=contanerRef.current;if(!elem) return;const domRect = elem.getBoundingClientRect();if(!domRect) return;const {bottom} = domRect;if(bottom <= document.body.clientHeight){console.log("tryLoadMore");}},{wait:1000})

并没实现,采取下面这种方法实现了,不知道为什么

 //触发加载 ---- 防抖const containerRef = useRef<HTMLDivElement>(null)const {run:loadMore} =useDebounceFn(()=>{const elem=containerRef.current;if(!elem) return;const domRect = elem.getBoundingClientRect();if(!domRect) return;const {bottom} = domRect;if(bottom <= window.innerHeight){console.log("bottom = ",bottom);console.log('body = ',window.innerHeight);console.log("tryLoadMore");}},{wait:1000})

当keyword变化时没有重新loadMore

因为添加了滑到底部触发条件

//3.keyword变化时,重置信息(1.时添加了滑动到底部触发,不能实现keyword变化时刷新页面)useEffect(()=>{setList([])setPage(1)setTotal(0)},[keyword])

标星

后端接口

 //更新问卷{url: '/api/question/:id',method: 'patch',response: () => {return {errno: 0,}}}

前端请求方法

//更新问卷export async function updateQuestinService(id:string,opt:{[key:string]:any}): Promise<ResDataType>{const url=`/question/${id}`const data = ( await axios.patch(url,opt) ) as ResDataType;return data;}

前端发起请求

 const {loading:changeStarLoading , run : changeStar} = useRequest(async()=>{const data = await updateQuestinService(id,{isStar:!isStarState});return data;},{manual: true,onSuccess: () => {setIsStarState(!isStarState);message.success('操作成功');},})

复制

 //复制问卷{url: '/api/question/duplicate/:id',method: 'post',response: () => {return {errno: 0,data:{id:Random.id()}}// 复制问卷export async function duplicateQuestinService(id : string ): Promise<ResDataType>{const url=`/question/duplicate/${id}`const data = ( await axios.post(url) ) as ResDataType;return data;}

删除 / 恢复

利用isdDelete 字段

 //更新问卷{url: '/api/question/:id',method: 'patch',response: () => {return {errno: 0,}}},//更新问卷export async function updateQuestinService(id:string,opt:{[key:string]:any}): Promise<ResDataType>{const url=`/question/${id}`const data = ( await axios.patch(url,opt) ) as ResDataType;return data;}

彻底删除

  //批量彻底删除{url: '/api/question/delete',method: 'delete',response: () => {return {errno: 0,}}}//批量彻底删除export async function deleteQuestinService(ids:string[]): Promise<ResDataType>{const url=`/question/delete`const data = ( await axios.delete(url,{data:ids}) ) as ResDataType;return data;}

刷新的两种方式

refresh

在这里插入图片描述

在这里插入图片描述

自己写逻辑

在这里插入图片描述


http://www.ppmy.cn/embedded/3525.html

相关文章

Aws Nat Gateway

要点 NAT网关要能访问外网&#xff0c;所以需要部署在有互联网网关的Public子网中。 关键&#xff1a; NAT网关创建是选择子网&#xff0c;一定要选择公有子网&#xff08;有互联网网关子网&#xff09; 特别注意&#xff1a; 新建nat网关的时候&#xff0c;选择的子网一定…

ubuntu系统下opencv的编译安装

ubuntu系统下opencv的编译安装 参考https://blog.csdn.net/KIK9973/article/details/118830187 1 安装准备 1.1安装依赖环境(Ubuntu18.04) 下载opencv的依赖&#xff0c;其中第三行的依赖是可选的&#xff0c;前两行的依赖则是必要的。 sudo apt-get install build-essent…

Flutter 插件站新升级: 加入优秀 GitHub 开源项目

Flutter 插件站新升级: 加入优秀 GitHub 开源项目 视频 https://youtu.be/qa49W6FaDGs https://www.bilibili.com/video/BV1L1421o7fV/ 前言 原文 https://ducafecat.com/blog/flutter-awesome-github-repo-download 这几天晚上抽空把 Flutter 插件站升级&#xff0c;现在支…

服务器清理挖矿问题

top -c ps -ef netstat -antp # 查所有端口链接 ls -al /proc/$PID/exe # 查执行文件 kill -9 $PID # 杀进程 // 查文件 /usr/lib/systemd/system /usr/lib/systemd/system/multi-user.target.wants /etc/rc.local /etc/inittab /etc/rc0.d/ /etc/rc1.d/ /etc/rc2.d/…

分布式锁(Redis)

一、序言 本文和大家聊聊分布式锁以及常见的解决方案。 二、什么是分布式锁 假设一个场景&#xff1a;一个库存服务部署在上面三台机器上&#xff0c;数据库里有 100 件库存&#xff0c;现有 300 个客户同时下单。并且这 300 个客户均摊到上面的三台机器上&#xff08;即三台…

Python:腾讯云-轻量应用服务器-实现自动快照

Python&#xff1a;腾讯云-轻量应用服务器-实现自动快照 – WhiteNights Site 先说一下配置情况&#xff1a;轻量应用服务器一块系统盘。我没钱加盘&#xff0c;所以不知道多块盘的情况下这个脚本还能不能用。 官方文档给的代码已经很齐全了&#xff0c;只需要做点补充就能直…

MyBatis使用PageHelper分页插件

1、不使用PageHelper分页插件 模块名&#xff1a;mybatis-012-page CarMapper接口package org.example.mapper;import org.apache.ibatis.annotations.Param; import org.example.pojo.Car;import java.util.List;public interface CarMapper {/*** 分页查询* param startInd…

Windows11+Ubuntu20.04系统重装(升级为Ubuntu22.04)

事情起因是标题所对应的双系统中&#xff0c;Ubuntu老自动断电关机&#xff0c;一开始是跑大型程序才会关机&#xff0c;这两天愈演愈烈变成运行一个远程控制或者VSCode就会关机。一怒之下找了Dell在线客服&#xff0c;在对方引导下检测了硬件系统&#xff0c;发现没有明显故障…