React Hooks --- 分享自己开发中常用的自定义的Hooks (1)
为什么要使用自定义 Hooks
自定义 Hooks 是 React 中一种复用逻辑的机制,通过它们可以抽离组件中的逻辑,使代码更加简洁、易读、易维护。它们可以在多个组件中复用相同的逻辑,减少重复代码。
1、useThrottle
代码
import React,{ useRef, useState,useEffect } from "react";/*** useThrottle:一个节流的 hook,用于限制状态更新的频率。** @param {any} initialState 初始状态* @param {number} delay 节流间隔时间,默认为 500 毫秒* @returns {any} 节流后的状态*/
export const useThrottle = (initialState, delay = 5000) => {const [state, setState] = useState(initialState);const timeout = useRef();const nextValue = useRef(null);const hasNextValue = useRef(false);useEffect(() => {if (timeout.current) {nextValue.current = initialState;hasNextValue.current = true;} else {setState(initialState);const timeoutCallback = () => {if (hasNextValue.current) {setState(nextValue.current);hasNextValue.current = false;}timeout.current = undefined;};timeout.current = setTimeout(timeoutCallback, delay);}return () => {timeout.current && clearTimeout(timeout.current);}}, [initialState]);return state;
};
用法
import { useThrottle } from './useThrottle';const value = useThrottle(state, 500);
2、useVirtual
代码
import { useEffect, useState } from 'react';/*** useVirtual:一个虚拟滚动的 hook,用于优化长列表的渲染性能。** @param {object} listRef 列表的引用对象* @param {Array} list 初始列表数据* @param {boolean} isFullScreen 是否全屏显示* @returns {Array} 显示在视图中的列表数据和 padding 样式*/
export const useVirtual = (listRef, list, isFullScreen) => {const origin = list;let viewHeight = null;let itemHeight = 0;let dur = 0;const rootFontSize = parseInt(document.documentElement.style.fontSize);const [viewList, setViewList] = useState(list);const [startIndex, setStartIndex] = useState(0);const [endIndex, setEndIndex] = useState(0);const [padding, setPadding] = useState({paddingTop: 0,paddingBottom: 0,});useEffect(() => {init(listRef);}, []);useEffect(() => {initData(listRef.current);update();}, [startIndex]);function init(ref) {initData(ref.current);render(startIndex, dur + 1);eventBind(ref.current);}function initData(dom) {const target = isFullScreen ? document.documentElement : dom;viewHeight = isFullScreen ? target.offsetHeight : target.parentNode.offsetHeight;itemHeight = target.getElementsByClassName('virtual-item')[0].offsetHeight;dur = Math.floor(viewHeight / itemHeight);}function eventBind(dom) {const eventTarget = isFullScreen ? window : dom.parentNode;eventTarget.addEventListener('scroll', handleScroll, false);}function render(startIndex, endIndex) {setViewList(() => origin.slice(startIndex, endIndex));setEndIndex(() => startIndex + dur + 1);}function handleScroll(e) {e.stopPropagation();const target = isFullScreen ? document.documentElement : listRef.current.parentNode;setStartIndex(() => Math.floor(target.scrollTop / itemHeight));}function update() {if (startIndex === endIndex) return;setEndIndex(() => startIndex + dur);render(startIndex, endIndex);setPadding(() => {return {paddingTop: (startIndex * itemHeight) / rootFontSize,paddingBottom: ((origin.length - endIndex) * itemHeight) / rootFontSize,};});}return [viewList, padding];
};
用法
import { useRef } from 'react';
import { useVirtual } from './useVirtual';const listRef = useRef();
const [viewList, padding] = useVirtual(listRef, initialList, false);
3、useCopyToClipboard
代码
import { message } from 'antd';/*** useCopyToClipboard:一个 hook,用于复制文本到剪贴板。** @returns {Array} 包含单个函数 `handleCopy`,用于复制文本到剪贴板*/
const useCopyToClipboard = () => {function handleCopy(text) {if (text) {let input = document.createElement('input');input.type = 'text';input.value = text;input.style.position = 'fixed';input.style.opacity = '0';document.body.appendChild(input);input.select();if (document.execCommand('copy')) {message.success('复制成功');} else {message.error('复制失败');}document.body.removeChild(input);} else {message.error('复制失败');}}return [handleCopy];
};export default useCopyToClipboard;
用法
import useCopyToClipboard from './useCopyToClipboard';const [handleCopy] = useCopyToClipboard();const copyText = () => {handleCopy('需要复制的文本');
};
4、useSmoothEnter
代码
import { useState, useEffect, useRef } from 'react';/*** useSmoothEnter:一个 hook,在 DOM 元素进入视口时添加平滑的进入动画。** @returns {object} ref - 一个可以附加到 DOM 元素的 ref 对象,用于动画效果*/
const useSmoothEnter = () => {const ref = useRef(null);const [isVisible, setIsVisible] = useState(false);const [animationStyle, setAnimationStyle] = useState({animation: '',animationPlayState: 'paused',});useEffect(() => {const observer = new IntersectionObserver((entries) => {const [entry] = entries;setIsVisible(entry.isIntersecting);});const element = ref.current;if (element) {observer.observe(element);return () => {observer.unobserve(element);};}}, [ref]);useEffect(() => {if (isVisible) {setAnimationStyle({animation: 'enterAnimation 1s ease',animationPlayState: 'running',});}}, [isVisible]);useEffect(() => {const element = ref.current;if (element) {element.style.animation = animationStyle.animation;element.style.animationPlayState = animationStyle.animationPlayState;}}, [animationStyle]);return ref;
};export default useSmoothEnter;
用法
import useSmoothEnter from './useSmoothEnter';const ref = useSmoothEnter();return <div ref={ref} className="animated-element">内容</div>;
相关文章:
React Hooks --- 分享自己开发中常用的自定义的Hooks (1)
为什么要使用自定义 Hooks 自定义 Hooks 是 React 中一种复用逻辑的机制,通过它们可以抽离组件中的逻辑,使代码更加简洁、易读、易维护。它们可以在多个组件中复用相同的逻辑,减少重复代码。 1、useThrottle 代码 import React,{ useRef,…...
uniapp H5页面设置跨域请求
记录一下本地服务在uniapp H5页面访问请求报跨域的错误 这是我在本地起的服务端口号为8088 ip大家可打开cmd 输入ipconfig 查看 第一种方法 在源码视图中配置 "devServer": {"https": false, // 是否启用 https 协议,默认false"port&q…...
使用myCobot280和OAK-D OpenCV DepthAI摄像头制作一个实时脸部跟踪的手机支架!
引言 由于YouTube和Netflix的出现,我们开始躺着看手机。然而,长时间用手拿着手机会让人感到疲劳。这次我们制作了一个可以在你眼前保持适当距离并调整位置的自动移动手机支架,让你无需用手拿着手机。请务必试试! 准备工作 这次我们…...
Xilinx FPGA:vivado关于单端ROM的一个只读小实验
一、实验要求 将生成好的voe文件里的数据使用rom读取出来,采用串口工具发送给电脑(当按键来临时)。 二、程序设计 按键消抖模块: timescale 1ns / 1ps module key_debounce(input sys_clk ,input rst_n…...
集成学习(一)Bagging
前边学习了:十大集成学习模型(简单版)-CSDN博客 Bagging又称为“装袋法”,它是所有集成学习方法当中最为著名、最为简单、也最为有效的操作之一。 在Bagging集成当中,我们并行建立多个弱评估器(通常是决策…...
Docker 中查看及修改 Redis 容器密码的实用指南
在使用 Docker 部署 Redis 容器时,有时我们需要查看或修改 Redis 的密码。本文将详细介绍如何在 Docker 中查看和修改 Redis 容器的密码,帮助你更好地管理和维护你的 Redis 实例。 一、查看 Redis 容器密码 通常在启动 Redis 容器时,我们会…...
CH09_JS的循环控制语句
第9章:Javascript循环控制语句 本章目标 掌握break关键字的使用掌握continue关键字的使用 课程回顾 for循环的特点和语法while循环的特点和语法do-while循环的特点和语法三个循环的区别 讲解内容 1. break关键字 为什么要使用break关键字 生活中,描…...
Python实现Mybatis Plus
Python实现Mybatis Plus from flask import g from sqlalchemy import asc, descclass QueryWrapperBuilder:conditions {}order_by_info {}def __new__(cls, *args, **kwargs):obj super(QueryWrapperBuilder, cls).__new__(cls)return objdef __init__(self, obj):self.o…...
卷积神经网络和Vision Transformer的对比之归纳偏置
卷积神经网络(CNN)和视觉变换器(Vision Transformer,ViT)是两种常用于图像处理的深度学习模型。它们各有优缺点,其中一个重要的区别在于它们对图像数据的“归纳偏置”(inductive bias࿰…...
Java之网络面试经典题(一)
目录 编辑 一.Session和cookie Cookie Session 二.HTTP和HTTPS的区别 三.浅谈HTTPS为什么是安全的? 四.TCP和UDP 五.GET和Post的区别 六.forward 和 redirect 的区别? 本专栏全是博主自己收集的面试题,仅可参考,不能相…...
Failed to download metadata for repo ‘docker-ce-stable‘
这个问题是由于在安装 clamav 和 clamav-update 时,无法下载 Docker CE Stable 库的元数据,可能的原因是网络连接超时或访问该网址受限。以下是一些可能的解决办法: 检查网络连接: 确保服务器的网络连接正常,尤其是与互…...
vant拍摄视频上传以及多张图片上传
数据定义 data() {return {fileList: [],vedioList: [],formData: ,fileTypes: image/png,image/jpeg,image/jpg,image/jpeg,} }, beforeMount() {this.formData new FormData() },拍摄视频上传 <van-uploaderv-if"radio 1"v-model"vedioList"accep…...
如何用手机拍出高级感黑白色调照片?华为Pura70系列XMAGE演绎黑白艺术
在影像的世界里,色彩可以让画面更丰富,更具有表现力,往往也能带来更多的视觉冲击。但有时候,黑白却有着一种独特的魅力。华为Pura 70系列XMAGE黑白风格,则给我们了一把通过纯粹艺术大门的钥匙。 XMAGE黑白并非简单的色…...
Cartographer前后端梳理
0. 简介 最近在研究整个SLAM框架的改进处,想着能不能从Cartographer中找到一些亮点可以用于参考。所以这一篇博客希望能够梳理好Cartographer前后端优化,并从中得到一些启发。carto整体是graph-based框架,前端是scan-map匹配,后端…...
Java面试题系列 - 第3天
题目:Java集合框架详解与高效使用策略 背景说明:Java集合框架是Java标准库的重要组成部分,提供了一系列容器类,如List、Set、Map等,用于存储和操作集合数据。熟练掌握集合框架的使用,对于编写高效、健壮的…...
【Spring Boot】Spring Boot简介
1、概述 Spring Boot是一个用于创建独立、生产级别的基于Spring的应用程序的开发框架。旨在简化Spring应用的初始搭建和开发过程。它通过自动配置和大量默认配置,使得开发者能够快速搭建一个独立的Spring应用,无需进行大量的手动配置。 2、主要特点 快…...
Akamai+Noname强强联合 | API安全再加强
最近,Akamai正式完成了对Noname Security的收购。本文我们将向大家介绍,经过本次收购后,Akamai在保护API安全性方面的后续计划和未来愿景。 Noname Security是市场上领先的API安全供应商之一,此次收购将让Akamai能更好地满足日益增…...
第四届BPAA算法大赛成功举办!共研算法未来
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…...
2024第三届中国医疗机器人大会第一轮通知
2024第三届中国医疗机器人大会第一轮通知 大会背景 医疗机器人技术正以前所未有的速度在主流医学领域取得卓越进展,新应用、新技术不断涌现,使得该领域在过去一年中取得了令人惊叹的增长。然而,这仅仅是冰山一角,未来的发展空间仍…...
常见算法和Lambda
常见算法和Lambda 文章目录 常见算法和Lambda常见算法查找算法基本查找(顺序查找)二分查找/折半查找插值查找斐波那契查找分块查找扩展的分块查找(无规律的数据) 常见排序算法冒泡排序选择排序插入排序快速排序递归快速排序 Array…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
