Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJs: Prevent multiple times button press

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 its first use.

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.

How could I enforce the button to get disabled or go away altogether the instant it's being clicked?

like image 551
Iulius Curt Avatar asked Feb 10 '16 12:02

Iulius Curt


People also ask

How do you disable a button once it is clicked in React?

Use the disabled prop to disable a button in React, e.g. <button disabled={true}>Click</button> . You can use the prop to conditionally disable the button based on the value of an input field or another variable or to prevent multiple clicks to the button.

How do I turn off multiple buttons in React?

To prevent multiple button presses with React, we can set the disabled prop to true when the button is clicked. to add the disabled state with the useState hook. We set the initial value of the state to false . Then we set the disabled prop of the button to the disabled state.


2 Answers

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

// 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> 
like image 189
cquezel Avatar answered Sep 22 '22 08:09

cquezel


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

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.

<button    ref={btn => { this.btn = btn; }}    onClick={this.onClickUploadFile} >Send</button>   this.btn.setAttribute("disabled", "disabled"); this.btn.removeAttribute("disabled"); 

Update: Using react hooks

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> 

here is a small example using the code you provided https://jsfiddle.net/69z2wepo/30824/

like image 25
eltonkamami Avatar answered Sep 22 '22 08:09

eltonkamami