webentwicklung-frage-antwort-db.com.de

ReactJs: Mehrmaliges Drücken der Taste verhindern

In meiner React-Komponente habe ich eine Schaltfläche, die dazu dient, einige Daten über AJAX zu senden, wenn Sie darauf klicken. Ich muss nur das erste Mal passieren, d. H. Die Schaltfläche nach der ersten Verwendung deaktivieren.

Wie versuche ich das:

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>
    );
  }

});

Ich denke, dass die Statusvariable showUploadButton nicht sofort aktualisiert wird, was die React-Dokumente erwarten.

Wie kann ich die Schaltfläche erzwingen, um in dem Moment, in dem sie angeklickt wird, deaktiviert zu werden oder ganz wegzugehen?

21
Iulius Curt

Sie können die Schaltfläche nach dem Klicken deaktivieren und auf der Seite belassen (nicht anklickbares Element).

Um dies zu erreichen, müssen Sie dem Button-Element einen Ref hinzufügen

<button ref="btn" onClick={this.onClickUploadFile}>Send</button>

und deaktivieren Sie dann die Schaltfläche onClickUploadFile

this.refs.btn.setAttribute("disabled", "disabled");

Sie können dann die deaktivierte Schaltfläche entsprechend formatieren, um dem Benutzer ein Feedback zu geben

.btn:disabled{ /* styles go here */}

Wenn nötig, stellen Sie sicher, dass Sie es erneut mit aktivieren

this.refs.btn.removeAttribute("disabled");

Update: Die bevorzugte Methode zum Umgang mit Refs in React ist eine Funktion und keine Zeichenfolge.

<button 
  ref={btn => { this.btn = btn; }} 
  onClick={this.onClickUploadFile}
>Send</button>


this.btn.setAttribute("disabled", "disabled");
this.btn.removeAttribute("disabled");

hier ist ein kleines Beispiel mit dem von Ihnen bereitgestellten Code https://jsfiddle.net/69z2wepo/30824/

24
eltonkamami

Getestet als funktionierende: 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);
15
zvona

Die Lösung besteht darin, den Zustand unmittelbar nach dem Eintritt in den Handler zu überprüfen. React garantiert, dass setState in interaktiven Ereignissen (z. B. Klicken) an der Browserereignisgrenze gelöscht wird. 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>
11
cquezel
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();

Ausgabe

exampleMethod executed for the first time
exampleMethod can be executed only once
0
Ashok R

Sie können versuchen, mit React Hooks den Komponentenstatus einzustellen.

import React, { setState } from 'react';

const Button = () => {
  const [double, setDouble] = setState(false);
  return (
    <button
      disabled={double}
      onClick={() => {
        // doSomething();
        setDouble(true);
      }}
    />
  );
};

export default Button;

Stellen Sie sicher, dass Sie die ^16.7.0-alpha.x-Version von react und react-dom verwenden.

Hoffe das hilft dir!

0
slorenzo

Wenn Sie möchten, verhindern Sie einfach die Übermittlung.

Wie wäre es mit lodash.js debounce 

Einen plötzlichen Stoß von Ereignissen (z. B. Tastatureingaben) zu einem einzigen Ereignis zusammenfassen.

https://lodash.com/docs/4.17.11#debounce

<Button accessible={true}
    onPress={_.debounce(async () => {
                await this.props._selectUserTickets(this.props._accountId)
    }, 1000)}
></Button>
0
Juneho Nam