实现分页 , 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;
}