Javascript ReactJs:防止多次按下按钮
在React组件中,我有一个按钮,用于在单击时通过AJAX发送一些数据。我只需要在第一次使用时使用,即在第一次使用后禁用按钮 我是如何做到这一点的:Javascript ReactJs:防止多次按下按钮,javascript,reactjs,react-jsx,Javascript,Reactjs,React Jsx,在React组件中,我有一个按钮,用于在单击时通过AJAX发送一些数据。我只需要在第一次使用时使用,即在第一次使用后禁用按钮 我是如何做到这一点的: var UploadArea = React.createClass({ getInitialState() { return { showUploadButton: true }; }, disableUploadButton(callback) { this.setState({ showUp
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>
);
}
});
var UploadArea=React.createClass({
getInitialState(){
返回{
showUploadButton:真
};
},
禁用上载按钮(回调){
this.setState({showUploadButton:false},回调);
},
//在我开始尝试我能想到的一切之前,这是比较简单的
onClickUploadFile(){
如果(!this.state.showUploadButton){
返回;
}
此.disableUploadButton(函数()为){
$.ajax({
[...]
});
});
},
render(){
var上传按钮;
if(this.state.showUploadButton){
上传按钮=(
发送
);
}
返回(
{上传按钮}
);
}
});
我认为发生的是状态变量showUploadButton
没有立即更新,React文档说这是预期的
我如何强制按钮在被单击时被禁用或同时消失?您可以做的是在单击按钮后将其禁用,并将其保留在页面中(不可单击元素) 要实现这一点,您必须向button元素添加ref
<button ref="btn" onClick={this.onClickUploadFile}>Send</button>
然后,您可以相应地设置禁用按钮的样式,以便使用
.btn:disabled{ /* styles go here */}
如果需要,请确保使用重新启用它
this.refs.btn.removeAttribute("disabled");
更新:在React中处理ref的首选方法是使用函数而不是字符串
<button
ref={btn => { this.btn = btn; }}
onClick={this.onClickUploadFile}
>Send</button>
this.btn.setAttribute("disabled", "disabled");
this.btn.removeAttribute("disabled");
{this.btn=btn;}
onClick={this.onClickUploadFile}
>发送
此.btn.setAttribute(“禁用”、“禁用”);
此.btn.removeAttribute(“禁用”);
更新:使用react钩子
import {useRef} from 'react';
let btnRef = useRef();
const onBtnClick = e => {
if(btnRef.current){
btnRef.current.setAttribute("disabled", "disabled");
}
}
<button ref={btnRef} onClick={onBtnClick}>Send</button>
从'react'导入{useRef};
设btnRef=useRef();
const onBtnClick=e=>{
如果(btnRef.当前){
btnRef.current.setAttribute(“禁用”、“禁用”);
}
}
发送
下面是一个使用您提供的代码的小示例
作为工作件进行测试:
class UploadArea扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
isButtonDisabled:false
}
}
上传文件(){
//首先将isButtonDisabled设置为true
这是我的国家({
isButtonDisabled:正确
});
//那就做你的事
}
render(){
返回(
this.uploadFile()}
disabled={this.state.isButtonDisabled}>
上传
)
}
}
render(,document.body);
解决方案是在进入处理程序后立即检查状态。React保证在浏览器事件边界处刷新交互事件(如单击)中的setState。参考:
//在构造函数中
此.state={
禁用:false
};
//单击时的处理程序
handleClick=(事件)=>{
如果(此.state.disabled){
返回;
}
this.setState({disabled:true});
//发送
}
//渲染中
{this.state.disabled?'Sending…':'Send'}
如果需要,只需阻止提交即可
如何使用lodash.js debounce
将突发事件(如击键)分组为单个事件
{
等待此.props.\u选择用户票证(此.props.\u帐户ID)
}, 1000)}
>
您可以尝试使用设置
import React,{useState}来自“React”;
常量按钮=()=>{
const[double,setDouble]=useState(false);
返回(
{
//doSomething();
setDouble(真);
}}
/>
);
};
导出默认按钮;
确保您使用的是^16.7.0-alpha.x
版本或更高版本的react
和react dom
希望这对你有帮助
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();
输出
如果在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}
/>
)
}
import React,{useState}来自“React”;
从“@material ui/core/Button”导入按钮;
导出默认功能按钮(道具){
const[executing,setExecuting]=useState(false);
常数{
残废
onClick,
…其他道具
}=道具;
const onRealClick=async(事件)=>{
setExecuting(true);
试一试{
等待onClick();
}最后{
设置正在执行(假);
}
};
返回(
)
}
请在此处查看它的实际操作:
我们基本上扩展了按钮组件,并在onClick执行期间禁用了额外的行为。执行此操作的步骤:
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>
);
}
});
注意:您应该确保原始onClick操作是异步的,也就是说它返回承诺。通过使用
event.target
,您可以禁用单击的按钮。
创建并调用函数onClick
时使用箭头函数。不要忘记在参数中传递事件
看我的
代码如下:
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);
类按钮扩展React.Component{
建造师(道具){
超级(道具)
this.buttons=['A','B','C','D']
}
disableOnclick=(e)=>{
e、 target.disabled=true
}
render(){
返回(
{this.buttons.map((btn,索引)=>(
this.disableOnclick(e)}
>{btn}
))}
)}
}
render(,document.body);
您可以在onClick回调中获取元素引用,并从此处获取setAttribute
,例如:
<Button
onClick={(e) => {
e.target.setAttribute("disabled", true);
this.handler();
}}
>
Submit
</Button>
{
e、 target.setAttribute(“已禁用”,true);
this.handler();
}}
>
提交
这无法解决问题,因为React会取消状态更新通知。因此,总有一个延迟
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();
exampleMethod executed for the first time
exampleMethod can be executed only once
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}
/>
)
}
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);
<Button
onClick={(e) => {
e.target.setAttribute("disabled", true);
this.handler();
}}
>
Submit
</Button>