Javascript 在onClick事件中使用setTimeout来限制按钮的快速点击是否是一种不好的做法?
我有一个按钮,当本地useState钩子为true时被禁用,当为false时被启用。我的onClick事件调用一个handleclick函数,它做的第一件事是将这个钩子设置为true(如果它还不是true)。如果为true,则返回并退出函数。我有一个通知,当函数完成它所做的操作时弹出。我遇到的问题是,如果提交按钮被垃圾邮件发送,用户可以在submitButtonDisabled从false更新为true之前多次单击该按钮,并导致在禁用之前多次请求提交。到目前为止,我的解决方案是在handleClick方法上使用setTimeout()方法,以便submitButtonDisabled状态有时间更新。这是可行的,但我的直觉告诉我这是一个糟糕的做法 我不认为状态更新需要更长的时间,但从理论上讲,如果时间超过750ms(或我设置的时间),它将发送多个请求,而我又回到了原点。我愿意接受我的解决方案,因为它目前正在工作,但如果有更好的实践,我想知道并实施它。下面是一个缩写代码的示例Javascript 在onClick事件中使用setTimeout来限制按钮的快速点击是否是一种不好的做法?,javascript,reactjs,Javascript,Reactjs,我有一个按钮,当本地useState钩子为true时被禁用,当为false时被启用。我的onClick事件调用一个handleclick函数,它做的第一件事是将这个钩子设置为true(如果它还不是true)。如果为true,则返回并退出函数。我有一个通知,当函数完成它所做的操作时弹出。我遇到的问题是,如果提交按钮被垃圾邮件发送,用户可以在submitButtonDisabled从false更新为true之前多次单击该按钮,并导致在禁用之前多次请求提交。到目前为止,我的解决方案是在handleCl
const MyFunction= () => {
const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
const handleClick = () => {
if (submitButtonDisabled) {
return;
}
setSubmitButtonDisabled(true);
// do a bunch of stuff.....
// setSubmitButtonDisabled(false) in the resolve or reject of the async call
};
return (
<div className="main-div">
<button
className="button"
onClick={() => {
setSubmitButtonDisabled(true);
setTimeout(handleClick, 750);}}
>{submitButtonDisabled ? "Saving..." : "Submit"}</button>
</div>
);
}
constmyfunction=()=>{
const[submitButtonDisabled,setSubmitButtonDisabled]=使用状态(false);
常量handleClick=()=>{
如果(提交按钮禁用){
回来
}
setSubmitButtonDisabled(true);
//做一堆事情。。。。。
//在异步调用的解析或拒绝中设置SubmitButtonDisabled(false)
};
报税表(
{
setSubmitButtonDisabled(true);
setTimeout(handleClick,750);}
>{submitButtonDisabled?“正在保存…”:“提交”}
);
}
我不完全确定为什么react无法如此快速地重新渲染组件,或者为什么用户要如此快速地单击组件,但不管有没有比直接使用timeout更好的选项来确保函数只能调用一次。以下是几个例子:
submitButtonDisabled
为true时,在按钮上设置disabled
<button className="button" onClick={handleClick} disabled={submitButtonDisabled}>
{submitButtonDisabled ? 'Saving...' : 'Submit'}
</button>
{submitButtonDisabled?'Saving…':'Submit'}
import React, { useRef, useState } from 'react';
const MyFunction = () => {
const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
let hasClickBeenCalledThisRender = false;
const handleClick = () => {
if (submitButtonDisabled||hasClickBeenCalledThisRender) {
return;
}
hasClickBeenCalledThisRender = true;
setSubmitButtonDisabled(true);
// do a bunch of stuff.....
// setSubmitButtonDisabled(false) in the resolve or reject of the async call
};
return (
<div className="main-div">
<button className="button" onClick={handleClick}>
{submitButtonDisabled ? 'Saving...' : 'Submit'}
</button>
</div>
);
};
import React,{useRef,useState}来自“React”;
常量MyFunction=()=>{
const[submitButtonDisabled,setSubmitButtonDisabled]=使用状态(false);
让hasClickBeenCalledThisRender=false;
常量handleClick=()=>{
如果(submitButtonDisabled | |已单击已调用此渲染){
回来
}
hasClickBeenCalledThisRender=true;
setSubmitButtonDisabled(true);
//做一堆事情。。。。。
//在异步调用的解析或拒绝中设置SubmitButtonDisabled(false)
};
返回(
{submitButtonDisabled?'Saving…':'Submit'}
);
};
import React, { useRef, useState } from 'react';
const MyFunction = () => {
const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
const submitButtonDisabledRef = useRef(false);
const handleClick = () => {
if (submitButtonDisabledRef.current) {
return;
}
submitButtonDisabledRef.current = true;
setSubmitButtonDisabled(true);
// do a bunch of stuff.....
// setSubmitButtonDisabled(false) in the resolve or reject of the async call
// submitButtonDisabledRef.current = false
};
return (
<div className="main-div">
<button className="button" onClick={handleClick}>
{submitButtonDisabled ? 'Saving...' : 'Submit'}
</button>
</div>
);
};
import React,{useRef,useState}来自“React”;
常量MyFunction=()=>{
const[submitButtonDisabled,setSubmitButtonDisabled]=使用状态(false);
const submitButtonDisabledRef=useRef(false);
常量handleClick=()=>{
if(submitButtonDisabledRef.电流){
回来
}
submitButtonDisabledRef.current=真;
setSubmitButtonDisabled(true);
//做一堆事情。。。。。
//在异步调用的解析或拒绝中设置SubmitButtonDisabled(false)
//submitButtonDisabledRef.current=false
};
返回(
{submitButtonDisabled?'Saving…':'Submit'}
);
};
import React,{useRef,useState,usemo}来自'React';
从“lodash”导入{throttle};
常量MyFunction=()=>{
const[submitButtonDisabled,setSubmitButtonDisabled]=使用状态(false);
const handleClick=useMoom(()=>{
回油节气门(()=>{
如果(提交按钮禁用){
回来
}
setSubmitButtonDisabled(true);
}, 75);
},[submitButtonDisabled]);
返回(
{submitButtonDisabled?'Saving…':'Submit'}
);
};
const{
useRef,
useState,
使用备忘录,
使用效果,
使用回调
}=反应;
常数{debounce,throttle}=\uu0;
常量MyFunction=()=>{
const[submitButtonDisabled,setSubmitButtonDisabled]=使用状态(false);
const[numHandleClickRuns,setNumHandleClickRuns]=useState(0);
常数[
提交的文件不可禁用,
将SubmitDeBounce按钮设置为禁用状态
]=使用状态(假);
const[numhandledebouncclickruns,setnumhandledebouncclickruns]=useState(
0
);
常数[
提交已禁用的按钮,
将SubmitthRottle按钮设置为禁用
]=使用状态(假);
const[numHandleThrottleClickRuns,setNumHandleThrottleClickRuns]=useState(
0
);
const handleClick=事件=>{
setSubmitButtonDisabled(true);
setNumHandleClickRuns(num=>num+1);
//console.log('here')
设置超时(()=>{
//假异步调用
设置SubmitButtonDisabled(假);
}, 1000);
};
const handledebounclick=usedbouncefn(
事件=>{
设置SubmitDeBounceButtonDisabled(真);
setNumHandleDebouncClickRuns(num=>num+1);
//console.log('here')
设置超时(()=>{
import React, { useRef, useState, useMemo } from 'react';
import { throttle } from 'lodash';
const MyFunction = () => {
const [submitButtonDisabled, setSubmitButtonDisabled] = useState(false);
const handleClick = useMemo(() => {
return throttle(() => {
if (submitButtonDisabled) {
return;
}
setSubmitButtonDisabled(true);
}, 75);
}, [submitButtonDisabled]);
return (
<div className="main-div">
<button className="button" onClick={handleClick}>
{submitButtonDisabled ? 'Saving...' : 'Submit'}
</button>
</div>
);
};