React Native防止重复点击

ops/2024/9/20 7:17:08/ 标签: react native, react.js, javascript

项目中遇到了点击按钮重复提交的问题,防止重复点击首先是想到的是给点击事件一个定时,下次触发的条件是要距离上一次点击的时间大于N秒的之后才能再执行。

// 防重复点击函数
export const preventRepeatPress = {lastPressTi1me: 0,  	//  上次点击时间      repoTime: 2000,   		//  默认间隔时间2000  onPress(callback: () => void, waitTime: number = 2000) {let currTime = Date.now();if (currTime - this.lastPressTime > this.repoTime) {this.lastPressTime = currTime;this.repoTime = waitTime;         callback && callback();}},
};

在组件上的点击函数onPress中使用preventRepeatPress方法

<Button title="点击按钮" onPress={() => preventRepeatPress.onPress(() => fun())} /> 

在点击的时候可以传入设置间隔时间进行单独控制

() => preventRepeatPress.onPress(() => onCredit(),5000)

第二使用 setTimeout 函数

需要注意的是 timeout 需要放在全局也就是函数外部,否则的话每次调用 timeout 都会重新初始化导致防抖函数失去效果。

定义一个名为 debouncePlus 的函数,它接受一个函数 func,一个等待时间 wait(默认为 1000 毫秒)和一个 immediate 参数

// 定义一个变量 timeout,用于存储定时器的标识,变量作用域需要在函数外部
let timeout: string | number | NodeJS.Timeout | null | undefined = null;export const debouncePlus = (func: { apply: (arg0: any, arg1: IArguments) => void; },wait: number | undefined = 1000,immediate: any
) => {// 变量 result,用于存储函数执行的结果let result: any;// 定义一个内部函数 debounced,它将作为防抖后的函数被返回let debounced = function (this: any) {// 获取当前函数执行的上下文(this 指向)let context = this;// 获取传递给当前函数的参数let args = arguments;// 如果定时器已经存在,清除之前的定时器if (timeout) clearTimeout(timeout);// 如果 immediate 为真if (immediate) {// 如果 timeout 为 null,说明是第一次调用,应该立即执行函数let callNow = !timeout;// 设置一个新的定时器,在等待时间之后将 timeout 置为 nulltimeout = setTimeout(function () {timeout = null;}, wait);// 如果应该立即执行,则调用原始函数,并将结果存储在 result 中if (callNow) result = func.apply(context, args);}// 如果 immediate 为假else {// 设置一个新的定时器,在等待时间之后执行原始函数timeout = setTimeout(function () {func.apply(context, args);}, wait);}// 返回函数执行的结果(如果是 immediate 模式,可能是立即执行的结果;否则可能是 null)return result;};// 给 debounced 函数添加一个 cancel 方法,用于取消正在等待执行的定时器debounced.cancel = function () {clearTimeout(timeout);timeout = null;};// 返回防抖后的函数return debounced;
};

第三使用 hook

/*** 防抖hook*   const { run } = useDebounceFn(() => {setValue(value + 1)},{wait: 500,},);*/
import { useEffect, useMemo, useRef } from 'react';
import { debouncePlus } from './debounce-plus';const isDev = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test';
const isFunction = (value: unknown): value is (...args: any) => any => typeof value === 'function';interface DebounceOptions {wait?: number;leading?: boolean;trailing?: boolean;maxWait?: number;
}type noop = (...args: any[]) => any;function useDebounceFn<T extends noop>(fn: T, options?: DebounceOptions) {if (isDev) {if (!isFunction(fn)) {console.error(`useDebounceFn expected parameter is a function, got ${typeof fn}`);}}const fnRef = useLatest(fn);const wait = options?.wait ?? 1000;const debounced = useMemo(() =>debouncePlus((...args: Parameters<T>): ReturnType<T> => {return fnRef.current(...args);},wait,options,),[],);useUnmount(() => {debounced.cancel();});return {run: debounced,cancel: debounced.cancel,// flush: debounced.flush,};
}export default useDebounceFn;export const useUnmount = (fn: () => void) => {if (isDev) {if (!isFunction(fn)) {console.error(`useUnmount expected parameter is a function, got ${typeof fn}`);}}const fnRef = useLatest(fn);useEffect(() => () => {fnRef.current();},[],);
};export function useLatest<T>(value: T) {const ref = useRef(value);ref.current = value;return ref;
}

有好的思路欢迎评论交流


http://www.ppmy.cn/ops/112093.html

相关文章

【Qt】Qt C++ Widget中嵌入qml

1. 效果 2. 方法 使用QQuickWidget方式 QQuickWidget *view new QQuickWidget;view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));view->show();除了QQuickWidget方式还可以使用QQuickView方式&#xff0c;请自行查阅资料 3. 代码 3.1 工程目录 3.2 …

重生归来之挖掘stm32底层知识(1)——寄存器

概念理解 要使用stm32首先要知道什么是引脚和寄存器。 如下图所示&#xff0c;芯片通过这些金属丝与电路板连接&#xff0c;这些金属丝叫做引脚。一般做软件开发是不需要了解芯片是怎么焊的&#xff0c;只要会使用就行。我们平常通过编程来控制这些引脚的输入和输出&#xff0c…

小程序面试题七

一、微信小程序如何实现下拉刷新&#xff1f; 微信小程序实现下拉刷新的功能&#xff0c;并不是直接内置了一个下拉刷新的组件或API&#xff0c;但你可以通过监听页面的滚动事件来实现这一功能。以下是一个基本的实现步骤&#xff1a; 1. 监听页面的滚动事件 在小程序的页面配…

物联网之PWM呼吸灯、脉冲、LEDC

MENU 前言原理硬件电路设计软件程序设计analogWrite()函数实现呼吸灯效果LEDC输出PWM信号 前言 学习制作呼吸灯&#xff0c;通过LED灯的亮度变化来验证PWM不同电压的输出。呼吸灯是指灯光在单片机的控制之下完成由亮到暗的逐渐变化&#xff0c;感觉好像是人在呼吸。 原理 脉冲宽…

代码随想录 第九章 动态规划part07 198.打家劫舍 213.打家劫舍II 337.打家劫舍III

198.打家劫舍 class Solution { public:int rob(vector<int>& nums) {vector<int> dp(nums.size() 1, 0);nums.insert(nums.begin(), 0);dp[1] nums[1];int pre 1;for (int i 2; i < dp.size(); i){if (pre (i - 1)){if (dp[i - 1] < dp[i - 2] n…

Java笔记 【1】docker introduction

概述 为什么会有 docker 出现 Docker 理念 容器与虚拟机比较 容器发展简史 传统虚拟机技术 容器虚拟化技术 对比 优点 参考 概述 为什么会有 docker 出现 之前在服务器配置一个应用的运行环境&#xff0c;要安装各种软件&#xff0c;Java/RabbitMQ/MySQL/JDBC 驱动包等。安…

《C++》解密--顺序表

一、线性表 线性表是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈...... 线性表在【逻辑上】是线性结构…

Git 中的refs

在 Git 中&#xff0c;refs 是用来存储 Git 对象&#xff08;如提交、树、标签等&#xff09;的引用。每个 ref 都是一个指针&#xff0c;指向一个特定的 Git 对象。以下是 Git 中几种常见的 refs 及其含义&#xff1a; 1. refs/heads/ 表示&#xff1a;本地分支。 用途&…

Python Web开发中的扩展与插件开发:从自定义到打包与发布

Python Web开发中的扩展与插件开发&#xff1a;从自定义到打包与发布 目录 ⚙️ Flask中的自定义扩展开发&#x1f6e0;️ Django中的自定义插件开发&#x1f4e6; 插件的打包与发布详解&#x1f504; 版本控制与依赖管理&#xff08;pipenv、poetry&#xff09; 1. ⚙️ Fla…

vulnhub(8):pWnOS(还没信息收集就已经成功打点)

端口 nmap主机发现 nmap -sn 192.168.89.0/24 ​ Nmap scan report for 192.168.89.116 Host is up (0.00020s latency). ​ 116是新出现的机器&#xff0c;他就是靶机 nmap端口扫描 nmap -Pn 192.168.89.116 -p- --min-rate 10000 -oA nmap/scan 扫描开放端口保存到 nmap/sca…

基于spring的ssm整合

目录 基于spring的ssm整合 Spring 框架 SpringMVC 框架 MyBatis 框架 1.创建项目 2.导入依赖 3.导入sql 4.创建jdbc.propries文件 1&#xff09;mysql8以下 2&#xff09;mysql8以上的 5.创建mybatis-config.xml配置文件 6.创建spring-Config.xml文件 7.创建项目所需包和类 1&a…

宝塔部署python项目

宝塔部署-python项目文章浏览阅读559次&#xff0c;点赞11次&#xff0c;收藏9次。在添加项目后&#xff0c;选择项目所在的路径&#xff0c;然后命令行启动主py文件。具体先看项目日志&#xff0c;根据日志在环境管理处下载包。首先下载项目需要的python版本。_宝塔部署python…

【ShuQiHere】探索人工智能核心:机器学习的奥秘

【ShuQiHere】 &#x1f4a1; 什么是机器学习&#xff1f; 机器学习&#xff08;Machine Learning, ML&#xff09;是人工智能&#xff08;Artificial Intelligence, AI&#xff09;中最关键的组成部分之一。它使得计算机不仅能够处理数据&#xff0c;还能从数据中学习&#x…

JavaScript网页设计案例

JavaScript网页设计案例 一、引言 1. 背景介绍 JavaScript是一种高级的、解释型的编程语言&#xff0c;广泛应用于Web开发中&#xff0c;用于创建交互性强的网页。它能够操作文档对象模型&#xff08;DOM&#xff09;&#xff0c;处理事件&#xff0c;以及与服务器进行异步通…

Oracle中VARCHAR和VARCHAR2的区别

Oracle中VARCHAR和VARCHAR2的区别 VARCHAR2 默认类型&#xff0c;VARCHAR2是Oracle中最常见的可变长度字符串类型VARCHAR2不区分NULL和空字符串&#xff0c;这意味着NULL和空字符串在VARCHAR2类型中被视为相同的值最大长度为4000字节&#xff08;从Oracle 12c开始&#xff0c…

Go 中 Gin 框架的使用指南

Gin 是 Go 语言中一个非常流行的 Web 框架&#xff0c;因其性能优异、简单易用的 API 设计而受到开发者的喜爱。Gin 的优势在于其高效的路由处理和中间件机制&#xff0c;适用于构建 RESTful API 和其他 Web 应用。本文将介绍如何使用 Gin 框架开发一个简单的 Web 应用&#xf…

Qt 菜单栏、工具栏、状态栏、标签、铆接部件(浮动窗口) 设置窗口核心部件(文本编辑控件)的基本使用

效果 代码 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QToolBar> #include<QDebug> #include<QPushButton> #include<QStatusBar> #include<QLabel> #include<QDockWidget> #include<QTextEdi…

架构与业务的一致性应用:实现企业战略目标和合规管理的全面指南

在快速变化的数字经济中&#xff0c;信息架构已成为企业实现其业务目标、优化运营效率和确保数据安全的关键工具。一个成功的信息架构不仅要与企业的战略目标紧密对齐&#xff0c;还必须遵循日益严格的合规性要求&#xff0c;以保护敏感数据并满足法规规定。《信息架构&#xf…

Python--常见的数据格式转换

下面是几个常见的数据格式转换的示例&#xff0c;涵盖了一些常用的格式&#xff0c;如 CSV、XML、YAML 等。每个示例都会介绍如何从一种格式转换到另一种格式。 1. CSV 转 JSON CSV 文件通常以逗号分隔&#xff0c;行代表记录&#xff0c;列代表字段。我们可以使用 csv 和 js…

curl格式化json之jq工具?

jq 是一个轻量级的命令行工具&#xff0c;用于解析、操作和格式化 JSON 数据。它类似于 sed 或 awk&#xff0c;但专门用于处理 JSON 格式。使用 jq&#xff0c;你可以从复杂的 JSON 数据中提取所需的信息&#xff0c;格式化输出&#xff0c;进行数据筛选&#xff0c;甚至修改 …