um das Ereignis onChange nach Drücken der Eingabetaste aufzurufen


204

Ich bin neu in Bootstrap und habe mich an dieses Problem gehalten. Ich habe ein Eingabefeld und sobald ich nur eine Ziffer eingebe, wird die Funktion von onChangeaufgerufen, aber ich möchte, dass sie aufgerufen wird, wenn ich die Eingabetaste drücke, wenn die ganze Zahl eingegeben wurde. Das gleiche Problem für die Validierungsfunktion - sie ruft zu früh auf.

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
  //bsStyle: this.validationInputFactor(),
  placeholder: this.initialFactor,
  className: "input-block-level",
  onChange: this.handleInput,
  block: true,
  addonBefore: '%',
  ref:'input',
  hasFeedback: true
});

Antworten:


404

Laut React Doc können Sie Tastaturereignisse wie onKeyPressoder onKeyUpnicht anhören onChange.

var Input = React.createClass({
  render: function () {
    return <input type="text" onKeyDown={this._handleKeyDown} />;
  },
  _handleKeyDown: function(e) {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }
});

Update: Verwenden Sie React.Component

Hier ist der Code mit React.Component, der dasselbe tut

class Input extends React.Component {
  _handleKeyDown = (e) => {
    if (e.key === 'Enter') {
      console.log('do validate');
    }
  }

  render() {
    return <input type="text" onKeyDown={this._handleKeyDown} />
  }
}

Hier ist die jsfiddle .

Update 2: Verwenden Sie eine Funktionskomponente

const Input = () => {
  const handleKeyDown = (event) => {
    if (event.key === 'Enter') {
      console.log('do validate')
    }
  }

  return <input type="text" onKeyDown={handleKeyDown} />
}

2
Außerdem möchten Sie den Validierungsprozess an ein onBlurEreignis binden .
Wuct

5
Gleiche Lösung auf kompaktere Weise in Bezug auf den Eingabetext:<input ref='reference' onKeyPress={(e) => {(e.key === 'Enter' ? doSomething(this.refs.reference.value) : null)}} />
musemind

5
@musemind Eigentlich brauchen Sie nicht zu verwenden ref. <input onKeyPress={e => doSomething(e.target.value)}ist ausreichend.
Wuct

4
@musemind Der Sinn der Verwendung einer Klassenmethode anstelle einer Inline-Funktion besteht darin, zu vermeiden, dass bei jedem onKeyPressAuslösen eine neue Funktion erstellt wird. Es ist eine subtile Perf-Verbesserung.
Wuct

1
angehängte Geige funktioniert nicht mehr, bitte überprüfen Sie, trotzdem nette Antwort
Pardeep Jain

52

Sie können onKeyPress direkt im Eingabefeld verwenden. Die Funktion onChange ändert den Statuswert bei jeder Änderung des Eingabefelds und ruft nach Drücken der Eingabetaste eine Funktionssuche auf ().

<input
    type="text"
    placeholder="Search..."
    onChange={event => {this.setState({query: event.target.value})}}
    onKeyPress={event => {
                if (event.key === 'Enter') {
                  this.search()
                }
              }}
/>

Diese Antwort funktioniert für mich und nicht für die oben akzeptierte Antwort.
Karthik Shankar

Wenn Sie eine schwere Form haben, würde ich empfehlen, eine Funktion außerhalb der Rendermethode zu erstellen und als Referenz zu übergeben, da onKeyPress={this.yourFunc}sonst die Fettpfeilfunktion bei jedem Rendern neu erstellt wird.
Viktor

Dies funktioniert für den Fall, dass das onKeyPress-Ereignis auch für die Eingabe und den übergeordneten Fall geschrieben wird. Vielen Dank.
Naveen Kumar PG

OderonKeyPress={event => event.key === 'Enter' && this.search()}
camden_kid

24

Drücken Sie die Eingabetaste, wenn der Fokus auf ein Formularsteuerelement (Eingabe) normalerweise ein submit(onSubmit) -Ereignis im Formular selbst (nicht in der Eingabe) auslöst, sodass Sie Ihr Ereignis an this.handleInputdas Formular onSubmit binden können .

Alternativ können Sie es an das blurEreignis (onBlur) binden, das auftritt input, wenn der Fokus entfernt wird (z. B. das nächste Element, das den Fokus erhalten kann).


3
Dies ist weitaus sauberer als die Verwendung onKeyPress.
Blackus

1
Dachte, da das Ziel anders ist, event.target.valueist nicht verfügbar
Izkata

@Izkata was du sagst ist absolut richtig; Meine Antwort erfordert möglicherweise eine andere Art der Behandlung der Controller- handleInputMethode. Wenn Sie gemäß meiner Antwort vorgehen, werden Sie sowohl beim Drücken der Eingabetaste als auch beim Aktivieren einer submitTaste / Eingabe erfasst.
Luca

In den meisten Situationen in Web-Apps gibt es keine Formulare, nur Eingaben, daher ist diese Antwort für die meisten Anwendungsfälle nicht relevant, IMHO
vsync

@vsync es ist vielleicht nicht relevant für die Mehrheit, aber immer noch gültig für einen Teil - und definitiv nicht falsch, ich denke nicht, dass es eine Abwertung wert ist?
Luca

8

Sie können verwenden event.key

function Input({onKeyPress}) {
  return (
    <div>
      <h2>Input</h2>
      <input type="text" onKeyPress={onKeyPress}/>
    </div>
  )
}

class Form extends React.Component {
  state = {value:""}

  handleKeyPress = (e) => {
    if (e.key === 'Enter') {
      this.setState({value:e.target.value})
    }
  }

  render() {
    return (
      <section>
        <Input onKeyPress={this.handleKeyPress}/>
        <br/>
        <output>{this.state.value}</output>
      </section>
    );
  }
}

ReactDOM.render(
  <Form />,
  document.getElementById("react")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>


5

Reagiere auf Benutzer, hier ist eine Antwort der Vollständigkeit halber.

Reagiere auf Version 16.4.2

Sie möchten entweder für jeden Tastendruck aktualisieren oder den Wert nur beim Senden abrufen. Das Hinzufügen der Schlüsselereignisse zur Komponente funktioniert, es gibt jedoch Alternativen, wie in den offiziellen Dokumenten empfohlen.

Kontrollierte vs unkontrollierte Komponenten

Kontrolliert

Aus den Dokumenten - Formulare und kontrollierte Komponenten :

In HTML behalten Formularelemente wie Eingabe, Textbereich und Auswahl normalerweise ihren eigenen Status bei und aktualisieren ihn basierend auf Benutzereingaben. In React wird der veränderbare Status normalerweise in der Eigenschaft state von Komponenten gespeichert und nur mit setState () aktualisiert.

Wir können beides kombinieren, indem wir den Reaktionszustand zur „einzigen Quelle der Wahrheit“ machen. Dann steuert die React-Komponente, die ein Formular rendert, auch, was in diesem Formular bei nachfolgenden Benutzereingaben geschieht. Ein Eingabeformularelement, dessen Wert auf diese Weise von React gesteuert wird, wird als "gesteuerte Komponente" bezeichnet.

Wenn Sie eine gesteuerte Komponente verwenden, müssen Sie den Status für jede Änderung des Werts auf dem neuesten Stand halten. Dazu binden Sie einen Ereignishandler an die Komponente. In den Beispielen der Dokumente normalerweise das Ereignis onChange.

Beispiel:

1) Binden Sie den Ereignishandler im Konstruktor (Wert im Status beibehalten).

constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
}

2) Handlerfunktion erstellen

handleChange(event) {
    this.setState({value: event.target.value});
}

3) Formularübermittlungsfunktion erstellen (Wert wird aus dem Status übernommen)

handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
}

4) Rendern

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" value={this.state.value} onChange={this.handleChange} />
    </label>
    <input type="submit" value="Submit" />
</form>

Wenn Sie gesteuerte Komponenten verwenden, wird Ihre handleChangeFunktion immer ausgelöst, um den ordnungsgemäßen Status zu aktualisieren und beizubehalten. Der Status hat immer den aktualisierten Wert, und wenn das Formular gesendet wird, wird der Wert dem Status entnommen. Dies kann ein Nachteil sein, wenn Ihr Formular sehr lang ist, da Sie für jede Komponente eine Funktion erstellen oder eine einfache Funktion schreiben müssen, die die Wertänderung jeder Komponente behandelt.

Unkontrolliert

Aus der Komponente Docs - Uncontrolled

In den meisten Fällen empfehlen wir die Verwendung kontrollierter Komponenten zur Implementierung von Formularen. In einer gesteuerten Komponente werden Formulardaten von einer React-Komponente verarbeitet. Die Alternative sind unkontrollierte Komponenten, bei denen Formulardaten vom DOM selbst verarbeitet werden.

Um eine unkontrollierte Komponente zu schreiben, können Sie anstelle eines Ereignishandlers für jede Statusaktualisierung einen Verweis verwenden, um Formularwerte aus dem DOM abzurufen.

Der Hauptunterschied besteht darin, dass Sie nicht die onChangeFunktion, sondern onSubmitdas Formular verwenden, um die Werte abzurufen und bei Bedarf zu überprüfen.

Beispiel:

1) Binden Sie den Ereignishandler und erstellen Sie eine Referenz für die Eingabe im Konstruktor (kein Wert wird beibehalten)

constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
}

2) Formularübermittlungsfunktion erstellen (Wert wird aus der DOM-Komponente übernommen)

handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
}

3) Rendern

<form onSubmit={this.handleSubmit}>
    <label>
      Name:
      <input type="text" ref={this.input} />
    </label>
    <input type="submit" value="Submit" />
</form>

Wenn Sie unkontrollierte Komponenten verwenden, müssen Sie keine handleChangeFunktion binden . Wenn das Formular gesendet wird, wird der Wert aus dem DOM übernommen und die erforderlichen Validierungen können an dieser Stelle erfolgen. Es müssen auch keine Handlerfunktionen für eine der Eingabekomponenten erstellt werden.

Ihr Problem

Nun zu Ihrem Problem:

... Ich möchte, dass es aufgerufen wird, wenn ich die Eingabetaste drücke, wenn die ganze Nummer eingegeben wurde

Wenn Sie dies erreichen möchten, verwenden Sie eine unkontrollierte Komponente. Erstellen Sie keine onChange-Handler, wenn dies nicht erforderlich ist. Der enterSchlüssel sendet das Formular und die handleSubmitFunktion wird ausgelöst.

Änderungen, die Sie vornehmen müssen:

Entfernen Sie den onChange-Aufruf in Ihrem Element

var inputProcent = React.CreateElement(bootstrap.Input, {type: "text",
    //    bsStyle: this.validationInputFactor(),
    placeholder: this.initialFactor,
    className: "input-block-level",
    // onChange: this.handleInput,
    block: true,
    addonBefore: '%',
    ref:'input',
    hasFeedback: true
});

Behandeln Sie das Formular senden und validieren Sie Ihre Eingabe. Sie müssen den Wert von Ihrem Element in der Formularübermittlungsfunktion abrufen und dann validieren. Stellen Sie sicher, dass Sie den Verweis auf Ihr Element im Konstruktor erstellen.

  handleSubmit(event) {
      // Get value of input field
      let value = this.input.current.value;
      event.preventDefault();
      // Validate 'value' and submit using your own api or something
  }

Beispiel für die Verwendung einer unkontrollierten Komponente:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    // bind submit function
    this.handleSubmit = this.handleSubmit.bind(this);
    // create reference to input field
    this.input = React.createRef();
  }

  handleSubmit(event) {
    // Get value of input field
    let value = this.input.current.value;
    console.log('value in input field: ' + value );
    event.preventDefault();
    // Validate 'value' and submit using your own api or something
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
);

3

Sie können auch eine kleine Wrapper-Funktion wie diese schreiben

const onEnter = (event, callback) => event.key === 'Enter' && callback()

Dann verbrauchen Sie es auf Ihren Eingaben

<input 
    type="text" 
    placeholder="Title of todo" 
    onChange={e => setName(e.target.value)}
    onKeyPress={e => onEnter(e, addItem)}/>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.