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

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

自己写逻辑

版权声明:本文为博主作者:摇光93原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_73270720/article/details/137960518

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2024年4月22日
下一篇 2024年4月22日

相关推荐