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

在这里插入图片描述

在这里插入图片描述

自己写逻辑

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

每日两题3

礼物最大价值 class Solution { public:int jewelleryValue(vector<vector<int>>& frame) {int m frame.size(),n frame[0].size();vector<vector<int>> dp(m1,vector<int>(n1,0));for(int i 1; i < m;i){for(int j 1; j < n;j){d…

轻松点餐|餐饮小程序新玩法,美食触手可及

在企业经营领域&#xff0c;小程序正成为越来越多行业开展线上经营的重要工具。依托小程序等工具自主开发数字化经营平台&#xff0c;已经成为零售、餐饮等日常消费行业的趋势。餐饮行业向智能化快速迭代已势在必行&#xff0c;在此进程中&#xff0c;小程序成为了备受餐饮商家…

Mysql嵌套查询太简单了

1、子查询的分类 不相关查询&#xff1a; 子查询能独立执行 相关查询&#xff1a; 子查询不能独立运行 相关查询的执行顺序&#xff1a; 首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询, 若WHERE子句返回值为真&#xff0c;则取此元组放入结果…

SpringBoot整合PDF动态填充数据并下载

目录 目录 一、准备环境 二、iTextPDF介绍 三、步骤 四、访问查看结果 五、源代码参考 一、准备环境 ①下载一个万兴pdf软件 ②准备一个pdf 文件 二、iTextPDF介绍 这是一个用于生成PDF文档的Java库&#xff0c; 文档创建与修改&#xff1a;iTextPDF能够从零开始创建…

2024红明谷杯——Misc 加密的流量

2024红明谷杯——Misc 加密的流量 写在前面&#xff1a; 这里是贝塔贝塔&#xff0c;照例来一段闲聊 打比赛但赛前一波三折&#xff0c;又是成功签到的一个比赛 说起来比赛全名叫红明谷卫星应用数据安全场景赛&#xff0c;但好像真的跟卫星的关系不大&#xff0c;没有bin方…

面试Spring框架

什么是Spring框架&#xff1f; Spring框架是一个开源的Java应用程序框架&#xff0c;提供了综合的基础设施支持&#xff0c;用于开发Java企业应用程序。它涵盖了从基本的核心容器到全面的企业服务&#xff0c;可以用于构建任何规模的应用程序。 Spring框架的核心特性是什么&am…

Go之map详解

map的结构 map实现的两个关键数据结构 hmap 定义了map的结构bmap 定义了hmap.buckets中每个bucket的结构 // A header for a Go map. type hmap struct {count int // 元素的个数flags uint8 // 状态标记&#xff0c;标记map当前状态&#xff0c;是否正在写入B …

<计算机网络自顶向下> 可靠数据传输的原理(未完成)

可靠数据传输&#xff08;rdt&#xff1a;Reliable Data Transfer&#xff09;的原理 rdt在应用层&#xff0c;传输层和数据链路层都很重要是网络TOP10问题之一信道的不可靠特点决定了可靠数据传输rdt的复杂性rdt_send: 被上层&#xff08;如应用层&#xff09;调用&#xff0…

41.缺失的第一个正数

1. 解题原理&#xff1a; &#xff08;1&#xff09;对于一个有序的、不缺失元素的正数数组nums&#xff0c;元素nums[i]应当位于nums[i]-1的位置处。 &#xff08;2&#xff09;nums数组的长度为N&#xff0c;缺失的第一个正数如果不位于[1,N]&#xff0c;那么就肯定是N1 2. …

excel表格怎么设置密码?excel文件加密的两个方法

一、加密码的原理​ Excel加密码的原理主要基于加密算法和密钥管理。当用户为Excel文件或工作表设置密码时&#xff0c;Excel会采用一种加密算法对文件或工作表进行加密处理。这种加密算法通常是对称加密算法&#xff0c;如AES(高级加密标准)或DES(数据加密标准)。 二&#x…

海外住宅代理:推特账号为何容易被关小黑屋?

推特是全球最受欢迎的社交媒体之一&#xff0c;每天都有数以百万计的用户在这个平台上发布信息、分享观点和交流互动。然而&#xff0c;有些用户可能会发现他们的推特账号不幸陷入了所谓的“关小黑屋”状态&#xff0c;即账号被限制了可见度&#xff0c;导致发布的内容无法被其…

【数据分析面试】24.20个数据库问答题 (考察数据开发和实际应用能力)

作为数据从业者&#xff0c;日常工作除了对各类业务数据进行分析挖掘&#xff0c;也需要经常和数据库打交道、甚至也少不了要承担一些数据开发、数仓管理的工作。掌握数据库管理的基本概念和技术是至关重要的。无论是初学者还是从业者&#xff0c;理解数据库索引、范式、事务、…

四.音视频编辑-音频混合-概述

引言 当我们在前两篇博客中成功地构建了一个媒体组合&#xff0c;并且略过了音频部分时&#xff0c;我们意识到了我们需要对这个项目进行更详细的探讨。在本篇博客中&#xff0c;我们将会展示如何创建一个包含视频轨道、配音音频轨道以及背景音频轨道的完整媒体组合。更进一步…

游泳耳机哪个牌子好?体验与口碑兼顾的4大游泳耳机汇总!

最近的天气越来越炎热了&#xff0c;许多人选择游泳作为一种既能锻炼身体又能享受清凉的活动。而随着科技的发展&#xff0c;越来越多的运动爱好者希望在游泳时也能享受到音乐的乐趣。因此&#xff0c;游泳耳机应运而生&#xff0c;成为市场上的热门产品。然而&#xff0c;面对…

项目中的解耦小能手-观察者模式

目录 1.使用场景 2.什么是观察模式 3.观察者模式结构图 4.代码实现案例 4.1 subject代码实现 4.2 Observer类代码实现 5. 回顾总结 1.使用场景 当一个对象的改变需要同事改变其他对象的时候&#xff0c;如&#xff1a;订单中心-下单成功需要通知库存、物流和积分去做相应…

交流回馈老化测试负载优点和应用

交流回馈老化测试负载是用于模拟真实环境下设备运行状态的测试工具&#xff0c;通过对设备进行长时间的连续工作&#xff0c;以检测其性能的稳定性和可靠性。这种测试负载具有许多优点&#xff0c;并且在实际应用中有着广泛的用途。 在实际应用中&#xff0c;设备往往需要在各种…

Flask实战

from flask import Flask appFlask(__name__)点击Flask同时点击键盘ctrl即可查看Flask的默认初始化函数 def __init__(self,import_name: str,static_url_path: str | None None,static_folder: str | os.PathLike[str] | None "static",static_host: str | None …

产品心理学:为什么管钱的都是女生?

大家发现了吗&#xff1f;大部分公司女财务居多&#xff0c;而在家庭中&#xff0c;多数也是女生管钱。 为什么管钱的都是女生&#xff1f;答案文尾揭晓。 问题的答案&#xff0c;要从一个心理学名词“过度自信偏差”说起 用人话说&#xff0c;就是“迷之自信” 过度自信的例…

【剪映专业版】11音频的全流程剪辑操作

视频课程&#xff1a;B站有知公开课【剪映电脑版教程】 1.音乐素材 可能包含人声&#xff0c;音乐素材普遍比较长&#xff0c;几十秒到几分钟。要点击倒三角才会出现分类。 点击下载箭头下载素材&#xff1b;点击加号将素材增加到轨道&#xff1b;时间指示器在哪个地方&#…

Python | Leetcode Python题解之第35题搜索插入位置

题目&#xff1a; 题解&#xff1a; class Solution:def searchInsert(self, nums: List[int], target: int) -> int:left, right 0, len(nums) #采用左闭右开区间[left,right)while left < right: # 右开所以不能有,区间不存在mid left (right - left)//2 # 防止溢出…