score:58
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/
score:0
Keep it simple and inline:
<button type="submit"
onClick={event => event.currentTarget.disabled = true}>
save
</button>
But! This will also disable the button, when the form calidation failed! So you will not be able to re-submit.
In this case a setter is better.
This fix this set the disabled in the onSubmit
of the form:
// state variable if the form is currently submitting
const [submitting, setSubmitting] = useState(false);
// ...
return (
<form onSubmit={e => {
setSubmitting(true); // create a method to modify the element
}}>
<SubmitButton showLoading={submitting}>save</SubmitButton>
</form>
);
And the button would look like this:
import {ReactComponent as IconCog} from '../../img/icon/cog.svg';
import {useEffect, useRef} from "react";
export const SubmitButton = ({children, showLoading}) => {
const submitButton = useRef();
useEffect(() => {
if (showLoading) {
submitButton.current.disabled = true;
} else {
submitButton.current.removeAttribute("disabled");
}
}, [showLoading]);
return (
<button type="submit"
ref={submitButton}>
<main>
<span>{children}</span>
</main>
</button>
);
};
score:0
Another approach could be like so:
<button onClick={this.handleClick} disabled={isLoading ? "disabled" :""}>Send</button>
score:0
My approach is if event on processing do not execute anything.
class UploadArea extends React.Component {
constructor(props) {
super(props)
this.state = {
onProcess:false
}
}
uploadFile() {
if (!this.state.onProcess){
this.setState({
onProcess: true
});
// then do your thing
this.setState({
onProcess: false;
});
}
}
render() {
return (
<button
type='submit'
onClick={() => this.uploadFile()}>
Upload
</button>
)
}
}
ReactDOM.render(<UploadArea />, document.body);
score:1
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
score:1
You can get the element reference in the onClick callback and setAttribute
from there, eg:
<Button
onClick={(e) => {
e.target.setAttribute("disabled", true);
this.handler();
}}
>
Submit
</Button>
score:2
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.
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);
score:5
If you want, just prevent to submit.
How about using lodash.js debounce
Grouping a sudden burst of events (like keystrokes) into a single one.
https://lodash.com/docs/4.17.11#debounce
<Button accessible={true}
onPress={_.debounce(async () => {
await this.props._selectUserTickets(this.props._accountId)
}, 1000)}
></Button>
score:6
If you disable the button during onClick, you basically get this. A clean way of doing this would be:
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
We basically extend the Button component with the extra behaviour of being disabled during onClick execution. Steps to do this:
- 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
NOTE: You should ensure that the original onClick operation is async aka it is returning a Promise.
score:9
You can try using React Hooks to set the 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 or later of react
and react-dom
.
Hope this helps you!
score:21
Tested as working one: 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);
score:71
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>
Source: stackoverflow.com
Related Query
- ReactJs: Prevent multiple times button press
- Prevent multiple button color activation in ReactJS
- ReactJs : How to prevent componentWillUpdate from re-rendering multiple times
- Reactjs firing AJAX call multiple times a button is clicked (only want 1 per click!)
- ReactJS OnKeyPress to trigger a button press
- Prevent page jump on Button click? ReactJS
- Prevent re-rendering when state is changed multiple times during useEffect
- Reactjs - Data is being fetched multiple times
- How to prevent React Hook's useEffect from fetching data multiple times
- Slick slider render slide multiple times in reactjs
- ReactJS Modal opening multiple times when in a Loop
- Same event emitting multiple times in socket.io-client reactjs
- React page with multiple components of the same type. Show more of same components on button click, prevent re-rendering in original set
- How to prevent user multiple click submit button error for a login form in react?
- close multiple nested Material UI dialogs with browser back button - reactjs
- How can I get multiple ckEditor by click on a button in ReactJS using Hooks?
- Prevent eventListener from firing multiple times
- How to display a component inside a component multiple times on click in reactjs
- How to prevent assigning an event listener multiple times to an element when using Click Outside hooks?
- prevent multiple form submissions in reactjs
- Prevent multiple on-click events from firing: ReactJS
- How to get selected values from multiple dropdowns on button click using ReactJs
- How can I create a counter as components to use multiple times and create one button to reset all the counter in React JS?
- React / Axios prevent fetch API call get multiple times
- Certain views loading while others do not on back button press ReactJS
- call a same instance component multiple times ReactJS
- ReactJS How to prevent multiple API calls occurring in componentDidMount function
- redux saga api call is getting executed multiple times for single button click
- I have multiple onClick button and whenever I click 1 button all the same buttons triggers. Reactjs
- ReactJS - Function Based Component Rendering Multiple Times
More Query from same tag
- React.js: How to filter JSX element array on custom attribute?
- Cannot access this.props from string to function
- how to call UseState hook's state updater function inside a callback in react.js
- How to render with conditions in React
- react redux with asynchronous fetch
- Button Breaks React Form
- bind(this) not working on ajax success function
- Create an element spanning two Navbars
- React + TypeScript: Passing components in an Array as props
- React- How to pass props between two different Microfrontent component
- TypeError: dispatch is not a function. In React stateless component
- An example of using the 'react-leaflet' new useLeaflet() hook?
- React onMouseOver doesn't fire
- ReactJS Filter Box: Expected an assignment or function call and instead saw an expression no-unused-expressions
- Javascript React: Button not excuting function when button is pressed
- How to read json file from my src folder in my react app using webpack-dev-server?
- Adding a 'count clicks' function to a boolean button in React
- Route not rendering component
- I can't get Firebase to work on my React project
- Type Error: this.getOptions is not a function For style-loader
- How to use environment variables in ReactJS imported CSS?
- Navigation with React-router to subpage
- React Router: Exclude strings from generic `/:slug` path
- Select Next/Previous list item in React without re-rendering
- Why is React-app state not re-rendering here? How to get state to update in time
- React - filter nested array and update the state
- Import SVG in TypeScript React app with Webpack
- React: how to compare path with params witn concrete path
- how to show only login page using material-ui in reactjs?
- Why is my React form being seen as application/json when I set it to multipart/form-data? The file I upload is being seen as undefined