Javascript ReactJs:防止多次按下按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35315872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ReactJs: Prevent multiple times button press
提问by Iulius Curt
In my React component I have a button meant to send some data over AJAX when clicked. I need to happen only the first time, i.e. to disable the button after it's first use.
在我的 React 组件中,我有一个按钮,用于在单击时通过 AJAX 发送一些数据。我只需要第一次发生,即在第一次使用后禁用按钮。
How I'm trying to do this:
我如何尝试这样做:
var UploadArea = React.createClass({
getInitialState() {
return {
showUploadButton: true
};
},
disableUploadButton(callback) {
this.setState({ showUploadButton: false }, callback);
},
// This was simpler before I started trying everything I could think of
onClickUploadFile() {
if (!this.state.showUploadButton) {
return;
}
this.disableUploadButton(function() {
$.ajax({
[...]
});
});
},
render() {
var uploadButton;
if (this.state.showUploadButton) {
uploadButton = (
<button onClick={this.onClickUploadFile}>Send</button>
);
}
return (
<div>
{uploadButton}
</div>
);
}
});
What I think happens is the state variable showUploadButton
not being updated right away, which the React docs says is expected.
我认为发生的是状态变量showUploadButton
没有立即更新,React 文档说这是预期的。
How could I enforce the button to get disabled or go away all-together the instant it's being clicked?
我怎么能强制按钮在被点击的瞬间被禁用或消失?
采纳答案by eltonkamami
What you could do is make the button disabled after is clicked and leave it in the page (not clickable element).
您可以做的是在单击后禁用按钮并将其保留在页面中(不可单击元素)。
To achieve this you have to add a ref to the button element
为此,您必须向按钮元素添加一个引用
<button ref="btn" onClick={this.onClickUploadFile}>Send</button>
and then on the onClickUploadFile function disable the button
然后在 onClickUploadFile 函数上禁用按钮
this.refs.btn.setAttribute("disabled", "disabled");
You can then style the disabled button accordingly to give some feedback to the user with
然后,您可以相应地设置禁用按钮的样式,以便向用户提供一些反馈
.btn:disabled{ /* styles go here */}
If needed make sure to reenable it with
如果需要,请确保重新启用它
this.refs.btn.removeAttribute("disabled");
Update:the preferred way of handling refs in React is with a function and not a string.
更新:在 React 中处理 refs 的首选方式是使用函数而不是字符串。
<button
ref={btn => { this.btn = btn; }}
onClick={this.onClickUploadFile}
>Send</button>
this.btn.setAttribute("disabled", "disabled");
this.btn.removeAttribute("disabled");
here is a small example using the code you provided https://jsfiddle.net/69z2wepo/30824/
这是一个使用您提供的代码的小例子 https://jsfiddle.net/69z2wepo/30824/
回答by cquezel
The solution is to check the state immediately upon entry to the handler. React guarantees that setState?inside interactive events (such as click) is flushed at browser event boundary. Ref: https://github.com/facebook/react/issues/11171#issuecomment-357945371
解决方案是在进入处理程序时立即检查状态。React 保证 setState?inside 交互事件(例如单击)在浏览器事件边界刷新。参考:https: //github.com/facebook/react/issues/11171#issuecomment-357945371
// In constructor
this.state = {
disabled : false
};
// Handler for on click
handleClick = (event) => {
if (this.state.disabled) {
return;
}
this.setState({disabled: true});
// Send
}
// In render
<button onClick={this.handleClick} disabled={this.state.disabled} ...>
{this.state.disabled ? 'Sending...' : 'Send'}
<button>
回答by Samuli Hakoniemi
Tested as working one: http://codepen.io/zvona/pen/KVbVPQ
测试为工作之一:http: //codepen.io/zvona/pen/KVbVPQ
class UploadArea extends React.Component {
constructor(props) {
super(props)
this.state = {
isButtonDisabled: false
}
}
uploadFile() {
// first set the isButtonDisabled to true
this.setState({
isButtonDisabled: true
});
// then do your thing
}
render() {
return (
<button
type='submit'
onClick={() => this.uploadFile()}
disabled={this.state.isButtonDisabled}>
Upload
</button>
)
}
}
ReactDOM.render(<UploadArea />, document.body);
回答by slorenzo
You can try using React Hooksto set the Component State.
您可以尝试使用React Hooks来设置Component State。
import React, { useState } from 'react';
const Button = () => {
const [double, setDouble] = useState(false);
return (
<button
disabled={double}
onClick={() => {
// doSomething();
setDouble(true);
}}
/>
);
};
export default Button;
Make sure you are using ^16.7.0-alpha.x
version of react
and react-dom
.
确保您使用的^16.7.0-alpha.x
是react
和版本react-dom
。
Hope this helps you!
希望这对你有帮助!
回答by Vajk Hermecz
If you disable the button during onClick, you basically get this. A clean way of doing this would be:
如果您在 onClick 期间禁用按钮,您基本上会得到这个。一个干净的方法是:
import React, { useState } from 'react';
import Button from '@material-ui/core/Button';
export default function CalmButton(props) {
const [executing, setExecuting] = useState(false);
const {
disabled,
onClick,
...otherProps
} = props;
const onRealClick = async (event) => {
setExecuting(true);
try {
await onClick();
} finally {
setExecuting(false);
}
};
return (
<Button
onClick={onRealClick}
disabled={executing || disabled}
{...otherProps}
/>
)
}
See it in action here: https://codesandbox.io/s/extended-button-that-disabled-itself-during-onclick-execution-mg6z8
在这里查看它的实际效果:https: //codesandbox.io/s/extended-button-that-disabled-itself-during-onclick-execution-mg6z8
We basically extend the Button component with the extra behaviour of being disabled during onClick execution. Steps to do this:
我们基本上使用在 onClick 执行期间禁用的额外行为来扩展 Button 组件。执行此操作的步骤:
- Create local state to capture if we are executing
- Extract properties we tamper with (disabled, onClick)
- Extend onClick operation with setting the execution state
- Render the button with our overridden onClick, and extended disabled
- 如果我们正在执行,则创建要捕获的本地状态
- 提取我们篡改的属性(禁用,onClick)
- 通过设置执行状态扩展 onClick 操作
- 使用我们覆盖的 onClick 渲染按钮,并禁用扩展
NOTE: You should ensure that the original onClick operation is async aka it is returning a Promise.
注意:您应该确保原始的 onClick 操作是异步的,也就是返回一个 Promise。
回答by Juneho Nam
If you want, just prevent to submit.
如果您愿意,只需阻止提交即可。
How about using lodash.js debounce
怎么用 lodash.js debounce
Grouping a sudden burst of events (like keystrokes) into a single one.
将突发事件(如击键)分组为一个事件。
https://lodash.com/docs/4.17.11#debounce
https://lodash.com/docs/4.17.11#debounce
<Button accessible={true}
onPress={_.debounce(async () => {
await this.props._selectUserTickets(this.props._accountId)
}, 1000)}
></Button>
回答by Gazowski
By using event.target
, you can disabled the clicked button.
Use arrow function when you create and call the function onClick
. Don't forget to pass the event in parameter.
通过使用event.target
,您可以禁用单击的按钮。创建和调用函数时使用箭头函数onClick
。不要忘记在参数中传递事件。
See my codePen
查看我的代码笔
Here is the code:
这是代码:
class Buttons extends React.Component{
constructor(props){
super(props)
this.buttons = ['A','B','C','D']
}
disableOnclick = (e) =>{
e.target.disabled = true
}
render(){
return(
<div>
{this.buttons.map((btn,index) => (
<button type='button'
key={index}
onClick={(e)=>this.disableOnclick(e)}
>{btn}</button>
))}
</div>
)}
}
ReactDOM.render(<Buttons />, document.body);
回答by rudresh solanki
You can get the element reference in the onClick callback and setAttribute
from there, eg:
您可以在 onClick 回调中获取元素引用,然后setAttribute
从那里获取,例如:
<Button
onClick={(e) => {
e.target.setAttribute("disabled", true);
this.handler();
}}
>
Submit
</Button>
回答by Ashok R
const once = (f, g) => {
let done = false;
return (...args) => {
if (!done) {
done = true;
f(...args);
} else {
g(...args);
}
};
};
const exampleMethod = () => console.log("exampleMethod executed for the first time");
const errorMethod = () => console.log("exampleMethod can be executed only once")
let onlyOnce = once(exampleMethod, errorMethod);
onlyOnce();
onlyOnce();
output
输出
exampleMethod executed for the first time
exampleMethod can be executed only once