實(shí)現(xiàn)分頁 , LoadMore 上劃加載更多功能效果
分頁
page : 當(dāng)前頁
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) => {
//總條數(shù)
const {total} = props;
//當(dāng)前頁
const[page,setPage] = useState(1)
const[pageSize , setPageSize] = useState(10) //默認(rèn)設(shè)置10個(gè)一頁
//從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])
//當(dāng)page,pagesize 改變時(shí) , 觸發(fā)的函數(shù),跳轉(zhuǎn)頁面
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函數(shù)
const loadMore = () => {
console.log("loadMore");
}
//1. 當(dāng)頁面刷新,url參數(shù)(keyword)改變時(shí)觸發(fā)
const [searchParams] = useSearchParams();
useEffect(()=>{
loadMore()
},[searchParams])
//2. 滾動(dòng)頁面時(shí)觸發(fā)
useEffect(()=>{
if(hasMore)
{
window.addEventListener("scroll",loadMore)
}
//解綁事件!!!!!
return ()=>{
window.removeEventListener("scroll",loadMore)
}
})
發(fā)現(xiàn) 下滑時(shí)多次觸發(fā)事件
防抖
使用ahooks中的useDebounceFn
//觸發(fā)加載 ---- 防抖
const {run:loadMore} =useDebounceFn(
()=>{
console.log("tryLoadMore");
},
{
wait:1000
}
)
發(fā)現(xiàn)一滑動(dòng)就執(zhí)行l(wèi)oadmore
目標(biāo): 底部load出現(xiàn)在頁面中,就執(zhí)行l(wèi)oadMore
dom操作
useRef
<div ref={contanerRef}>
loadMore ....
</div>
//觸發(fā)加載 ---- 防抖
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
}
)
并沒實(shí)現(xiàn),采取下面這種方法實(shí)現(xiàn)了,不知道為什么
//觸發(fā)加載 ---- 防抖
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
}
)
當(dāng)keyword變化時(shí)沒有重新loadMore
因?yàn)樘砑恿嘶降撞坑|發(fā)條件
//3.keyword變化時(shí),重置信息(1.時(shí)添加了滑動(dòng)到底部觸發(fā),不能實(shí)現(xiàn)keyword變化時(shí)刷新頁面)
useEffect(()=>{
setList([])
setPage(1)
setTotal(0)
},[keyword])
標(biāo)星
后端接口
//更新問卷
{
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;
}
前端發(fā)起請求
const {loading:changeStarLoading , run : changeStar} = useRequest(
async()=>{
const data = await updateQuestinService(id,{isStar:!isStarState});
return data;
},
{
manual: true,
onSuccess: () => {
setIsStarState(!isStarState);
message.success('操作成功');
},
}
)
復(fù)制
//復(fù)制問卷
{
url: '/api/question/duplicate/:id',
method: 'post',
response: () => {
return {
errno: 0,
data:{
id:Random.id()
}
}
// 復(fù)制問卷
export async function duplicateQuestinService(id : string ): Promise<ResDataType>{
const url=`/question/duplicate/${id}`
const data = ( await axios.post(url) ) as ResDataType;
return data;
}
刪除 / 恢復(fù)
利用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.zghlxwxcb.cn/news/detail-855553.html
自己寫邏輯
文章來源地址http://www.zghlxwxcb.cn/news/detail-855553.html
到了這里,關(guān)于React + 項(xiàng)目(從基礎(chǔ)到實(shí)戰(zhàn)) -- 第九期的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!