Dans mon composant React, j'ai un bouton destiné à envoyer des données via AJAX lorsque l'utilisateur clique dessus. Je n'ai besoin que de la première fois, c'est-à-dire de désactiver le bouton après sa première utilisation.
Comment j'essaye de faire ceci:
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>
);
}
});
Je pense que ce qui se passe, c’est que la variable d’état showUploadButton
ne soit pas mise à jour immédiatement, ce que la documentation de React dit est prévue.
Comment puis-je imposer le bouton pour être désactivé ou partir tout de suite dès que l'utilisateur clique dessus?
Ce que vous pouvez faire est de rendre le bouton désactivé après avoir cliqué et de le laisser dans la page (élément non cliquable).
Pour ce faire, vous devez ajouter une référence à l'élément button.
<button ref="btn" onClick={this.onClickUploadFile}>Send</button>
puis sur la fonction onClickUploadFile désactiver le bouton
this.refs.btn.setAttribute("disabled", "disabled");
Vous pouvez ensuite styler le bouton désactivé en conséquence pour donner un retour à l'utilisateur avec
.btn:disabled{ /* styles go here */}
Si nécessaire, assurez-vous de le réactiver avec
this.refs.btn.removeAttribute("disabled");
Update: le moyen privilégié de gérer les références dans React consiste à utiliser une fonction et non une chaîne.
<button
ref={btn => { this.btn = btn; }}
onClick={this.onClickUploadFile}
>Send</button>
this.btn.setAttribute("disabled", "disabled");
this.btn.removeAttribute("disabled");
voici un petit exemple utilisant le code que vous avez fourni https://jsfiddle.net/69z2wepo/30824/
Testé comme fonctionnant: 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);
La solution consiste à vérifier l'état immédiatement après son entrée dans le gestionnaire. React garantit que setState dans les événements interactifs (tels que click) est vidé à la limite des événements du navigateur. 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>
Vous pouvez essayer d’utiliser React Hooks pour définir l’état Component .
import React, { setState } from 'react';
const Button = () => {
const [double, setDouble] = setState(false);
return (
<button
disabled={double}
onClick={() => {
// doSomething();
setDouble(true);
}}
/>
);
};
export default Button;
Assurez-vous que vous utilisez la version ^16.7.0-alpha.x
de react
et react-dom
.
J'espère que cela vous aide!
Si vous voulez, empêchez simplement de soumettre.
Que diriez-vous d'utiliser lodash.js debounce
Regrouper une rafale soudaine d'événements (comme des frappes au clavier) en un seul.
https://lodash.com/docs/4.17.11#debounce
<Button accessible={true}
onPress={_.debounce(async () => {
await this.props._selectUserTickets(this.props._accountId)
}, 1000)}
></Button>