Wie erhalte ich den Wert eines Eingabefeldes mit ReactJS?

188

Ich habe die folgende Reaktionskomponente:

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        var title = this.title;
        console.log(title);
    }

    render(){
        return (
            ...
            <form className="form-horizontal">
                ...
                <input type="text" className="form-control" ref={(c) => this.title = c} name="title" />
                ...
            </form>
            ...
            <button type="button" onClick={this.onSubmit} className="btn">Save</button>
            ...
        );
    }

};

Die Konsole gibt mir undefined- irgendwelche Ideen, was mit diesem Code falsch ist?

JoeTidee
quelle
7
this.onSubmit.bind(this);
Zerkms
Schön - möchte es als Antwort hinzufügen und ich werde es
abhaken
2
Was ist e.target.valueohne die Bindung?
Omarjmh
1
Wäre e.target.value nicht auf die Schaltfläche ausgerichtet, nicht auf das Eingabefeld?
JoeTidee
Sie müssen die onSubmitMethode beim Klicken (dh onClick={this.onSubmit.bind(this)}) an die Schaltfläche "Senden" (DOM-Element) binden . Und wenn Sie auf den Wert der Titeleingabe in dem Formular zugreifen möchten, das Sie verwenden können onSubmit(event) { const title = event.target.elements.title.value; }.
Montag

Antworten:

10

Sie sollten den Konstruktor unter der Klasse MyComponent verwenden, die React.Component erweitert

constructor(props){
    super(props);
    this.onSubmit = this.onSubmit.bind(this);
  }

Dann erhalten Sie das Ergebnis des Titels

Md. Maidul Islam
quelle
309

Hier gibt es drei Antworten, abhängig von der Version von React, mit der Sie arbeiten (gezwungen sind) und ob Sie Hooks verwenden möchten.

Das wichtigste zuerst:

Es ist wichtig zu verstehen , wie funktioniert Reaktion, so dass Sie die Dinge richtig tun können (protip: es ist Super läuft wert durch das Tutorial Übung Reagieren Sie auf die Website Reagieren Es ist gut geschrieben, und deckt alle Grundlagen in einer Weise , dass tatsächlich erklärt , wie zu tun ist . Dinge). "Richtig" bedeutet hier, dass Sie eine Anwendungsoberfläche schreiben, die zufällig in einem Browser gerendert wird. Die gesamte Arbeit an der Benutzeroberfläche erfolgt in React, nicht in "Was Sie gewohnt sind, wenn Sie eine Webseite schreiben" (aus diesem Grund sind React-Apps "Apps", keine "Webseiten").

Reaktionsanwendungen werden aus zwei Gründen gerendert:

  1. Die Eigenschaften der Komponente, die von dem übergeordneten Element deklariert wurden, erstellen eine Instanz dieser Komponente, die das übergeordnete Element während seines gesamten Lebenszyklus ändern kann
  2. der interne Status der Komponente, den sie während ihres gesamten Lebenszyklus selbst ändern kann.

Wenn Sie React verwenden, generieren Sie ausdrücklich keine HTML-Elemente und verwenden diese dann: Wenn Sie React anweisen, ein zu verwenden <input>, erstellen Sie beispielsweise kein HTML-Eingabeelement, und Sie weisen React an, ein React-Eingabeobjekt zu erstellen das passiert zu machen als HTML - Eingabeelement, und deren Ereignisbehandlung schaut, aber nicht kontrolliert wird durch das HTML - Element Eingabeereignisse.

Wenn Sie React verwenden, generieren Sie Elemente der Anwendungsbenutzeroberfläche, die dem Benutzer (häufig manipulierbare) Daten präsentieren, wobei die Benutzerinteraktion den Status der Komponente ändert, was dazu führen kann, dass ein Teil Ihrer Anwendungsschnittstelle den neuen Status wiedergibt. In diesem Modell ist der Status immer die letzte Autorität, nicht "welche UI-Bibliothek auch immer zum Rendern verwendet wird", die im Web das DOM des Browsers ist. Das DOM ist in diesem Programmiermodell fast ein nachträglicher Gedanke: Es ist nur das spezielle UI-Framework, das React gerade verwendet.

Im Fall eines Eingabeelements lautet die Logik also:

  1. Sie geben das Eingabeelement ein,
  2. Es passiert noch nichts mit Ihrem Eingabeelement. Das Ereignis wurde von React abgefangen und sofort beendet .
  3. Reagieren Sie, um das Ereignis an die Funktion weiterzuleiten, die Sie für die Ereignisbehandlung eingerichtet haben.
  4. Diese Funktion kann eine Statusaktualisierung planen.
  5. Wenn dies der Fall ist, führt React diese Statusaktualisierung aus (asynchron!) und löst rendernach der Aktualisierung einen Aufruf aus, jedoch nur, wenn die Statusaktualisierung den Status geändert hat .
  6. Erst nachdem dieses Rendern stattgefunden hat, zeigt die Benutzeroberfläche an, dass Sie "einen Buchstaben eingegeben" haben.

All dies geschieht in wenigen Millisekunden, wenn nicht sogar weniger. Es sieht also so aus, als hätten Sie das Eingabeelement so eingegeben, wie Sie es von "nur ein Eingabeelement auf einer Seite verwenden" gewohnt sind, aber das ist absolut nicht der Fall passierte.

Nachdem dies gesagt wurde, erfahren Sie, wie Sie Werte von Elementen in React erhalten:

Reagieren Sie 15 und darunter mit ES5

Um die Dinge richtig zu machen, hat Ihre Komponente einen Statuswert, der über ein Eingabefeld angezeigt wird. Wir können ihn aktualisieren, indem das UI-Element Änderungsereignisse an die Komponente zurücksendet:

var Component = React.createClass({
  getInitialState: function() {
    return {
      inputValue: ''
    };
  },

  render: function() {
    return (
      //...
      <input value={this.state.inputValue} onChange={this.updateInputValue}/>
      //...
    );
  },

  updateInputValue: function(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

Also haben wir das verwenden Reagieren tell updateInputValueFunktion die Interaktion mit dem Benutzer zu handhaben , verwenden , setStateum das Status - Update zu planen, und die Tatsache , dass renderzapft this.state.inputValuebedeutet , dass , wenn es rerenders nach dem Zustand zu aktualisieren, wird der Benutzer des Update Text sehen , auf dem, was sie eingegeben hat .

Nachtrag basierend auf Kommentaren

Angesichts der Tatsache, dass UI-Eingaben Statuswerte darstellen (überlegen Sie, was passiert, wenn ein Benutzer seine Registerkarte auf halbem Weg schließt und die Registerkarte wiederhergestellt wird. Sollten alle von ihnen eingegebenen Werte wiederhergestellt werden? Wenn ja, ist dies der Status). Das könnte Ihnen das Gefühl geben, dass ein großes Formular zehn oder sogar hundert Eingabeformulare benötigt, aber bei React geht es darum, Ihre Benutzeroberfläche auf wartbare Weise zu modellieren: Sie haben nicht 100 unabhängige Eingabefelder, Sie haben Gruppen verwandter Eingaben, also erfassen Sie jedes gruppieren Sie in einer Komponente und bauen Sie dann Ihr "Master" -Formular als Sammlung von Gruppen auf.

MyForm:
  render:
    <PersonalData/>
    <AppPreferences/>
    <ThirdParty/>
     ...

Dies ist auch viel einfacher zu warten als eine riesige Einzelformkomponente. Teilen Sie Gruppen in Komponenten mit Statusverwaltung auf, wobei jede Komponente nur für die Verfolgung einiger Eingabefelder gleichzeitig verantwortlich ist.

Möglicherweise haben Sie auch das Gefühl, dass es "mühsam" ist, den gesamten Code zu schreiben, aber das ist eine falsche Ersparnis: Entwickler, die nicht Sie sind, einschließlich zukünftiger Sie, profitieren tatsächlich stark davon, wenn all diese Eingaben explizit verknüpft werden, weil Dadurch können Codepfade viel einfacher nachverfolgt werden. Sie können jedoch jederzeit optimieren. Sie können beispielsweise einen Statuslinker schreiben

MyComponent = React.createClass({
  getInitialState() {
    return {
      firstName: this.props.firstName || "",
      lastName: this.props.lastName || "" 
      ...: ...
      ...
    }
  },
  componentWillMount() {
    Object.keys(this.state).forEach(n => {
      let fn = n + 'Changed';
      this[fn] = evt => {
        let update = {};
        update[n] = evt.target.value;
        this.setState(update);
      });
    });
  },
  render: function() {
    return Object.keys(this.state).map(n => {
      <input
        key={n} 
        type="text"
        value={this.state[n]}
        onChange={this[n + 'Changed']}/>
    });
  }
});

Natürlich gibt es verbesserte Versionen davon. Rufen Sie also https://npmjs.com auf und suchen Sie nach einer Lösung zum Verknüpfen des Reaktionsstatus, die Ihnen am besten gefällt. Bei Open Source geht es hauptsächlich darum, herauszufinden, was andere bereits getan haben, und dies zu verwenden, anstatt alles selbst von Grund auf neu zu schreiben.

Reagiere auf 16 (und 15.5 Übergangs) und 'moderne' JS

Ab React 16 (und Softstart mit 15.5) wird der createClassAufruf nicht mehr unterstützt und die Klassensyntax muss verwendet werden. Dies ändert zwei Dinge: die offensichtliche Klassensyntax, aber auch die thisKontextbindung, createClassdie "kostenlos" ausgeführt werden kann. Um sicherzustellen, dass die Dinge weiterhin funktionieren, stellen Sie sicher, dass Sie die Notation "Fettpfeil" verwenden, um thisanonyme Funktionen in onWhateverHandlern wie z das verwenden onChangewir im code hier:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: ''
    };
  }

  render() {
    return (
      //...
      <input value={this.state.inputValue} onChange={evt => this.updateInputValue(evt)}/>
      //...
    );
  },

  updateInputValue(evt) {
    this.setState({
      inputValue: evt.target.value
    });
  }
});

Möglicherweise haben Sie auch gesehen, dass Benutzer bindin ihrem Konstruktor alle Funktionen zur Ereignisbehandlung wie folgt verwenden:

constructor(props) {
  super(props);
  this.handler = this.handler.bind(this);
  ...
}

render() {
  return (
    ...
    <element onclick={this.handler}/>
    ...
  );
}

Tu das nicht.

Fast jedes Mal, wenn Sie verwenden bind, gilt das sprichwörtliche "Sie machen es falsch". Ihre Klasse definiert bereits den Objektprototyp und damit bereits den Instanzkontext. Nicht darüber legen bind; Verwenden Sie die normale Ereignisweiterleitung, anstatt alle Ihre Funktionsaufrufe im Konstruktor zu duplizieren, da diese Duplizierung Ihre Fehleroberfläche vergrößert und das Verfolgen von Fehlern erheblich erschwert, da das Problem möglicherweise in Ihrem Konstruktor liegt, anstatt dort, wo Sie Ihren Code aufrufen. Sie müssen auch andere, mit denen Sie arbeiten oder arbeiten möchten, mit Wartungsarbeiten belasten.

Ja, ich weiß, dass die Reaktionsdokumente sagen, dass es in Ordnung ist. Es ist nicht, tu es nicht.

Reagieren Sie 16.8 mit Funktionskomponenten mit Haken

Ab Reaktion 16.8 kann der Funktionskomponente (dh buchstäblich nur einer Funktion, die einige propsals Argument verwendet, so verwendet werden, als ob es sich um eine Instanz einer Komponentenklasse handelt, ohne jemals eine Klasse zu schreiben) auch mithilfe von Hooks der Status zugewiesen werden .

Wenn Sie keinen vollständigen Klassencode benötigen und eine einzelne Instanzfunktion ausreicht, können Sie jetzt mithilfe des useStateHooks eine einzelne Statusvariable und deren Aktualisierungsfunktion abrufen, die ungefähr genauso funktioniert wie die obigen Beispiele, außer ohne der setStateFunktionsaufruf:

import { useState } from 'react';

function myFunctionalComponentFunction() {
  const [input, setInput] = useState(''); // '' is the initial state value
  return (
    <div>
    <label>Please specify:</label>
    <input value={input} onInput={e => setInput(e.target.value)}/>
    </div>
  );
}

Früher war die inoffizielle Unterscheidung zwischen Klassen und Funktionskomponenten "Funktionskomponenten haben keinen Status", daher können wir uns nicht mehr dahinter verstecken: Der Unterschied zwischen Funktionskomponenten und Klassenkomponenten ist auf mehreren Seiten im Brunnen verteilt -geschriebene Reaktionsdokumentation (keine Abkürzung für eine Liner-Erklärung, die Sie bequem falsch interpretieren können!), die Sie lesen sollten, damit Sie wissen, was Sie tun, und somit wissen können, ob Sie die beste (was auch immer das für Sie bedeutet) Lösung ausgewählt haben, um sich selbst zu programmieren aus einem Problem heraus, das Sie haben.

Mike 'Pomax' Kamermans
quelle
4
Ich habe einige Online-Artikel gelesen, die besagen, dass es eine schlechte Idee ist, zu viel Status zu verwenden. In einer bestimmten Form meiner Bewerbung habe ich ungefähr 100 Formularfelder. Das Definieren einer Funktion zur Rettung des Staates scheint eine unnötig mühsame Art zu sein, Dinge zu tun. Wenn ich onClick = {this.onSubmit.bind (this)} verwenden kann, scheint dies ein guter Weg zu sein, um den Wert zu erhalten (wenn ich möchte, setzen Sie den Komponentenstatus) - ich würde mich über einige Kommentare dazu freuen.
JoeTidee
5
Schreiben Sie also intelligenteren Code. Formulareingaben sind definitiv Status (überlegen Sie, was passiert, wenn ein Benutzer seine Registerkarte auf halbem Weg schließt und die Registerkarte wiederhergestellt wird. Sollten alle von ihnen eingegebenen Werte wiederhergestellt werden? Ja? Das ist Status ). Schreiben Sie also ein bisschen Statuswartungscode. Facebook hat auch Hunderte von Formularwerten und ihre Lösung für den Wahnsinn war React. Es funktioniert wirklich gut. Eine Möglichkeit , Ihren Code ein wenig leichter zu machen, während nach wie vor Zustand verwendet wird , ist die Verwendung Zweiweg Zustand Verknüpfung wiederum erklärte auf der Website reagieren. Lesenswert! =)
Mike 'Pomax' Kamermans
2
Beachten Sie auch, dass "100 Felder" größtenteils irrelevant sind: Teilen Sie Ihr Formular auf, da es sich nicht um 100 Elemente handelt, sondern um mehrere Abschnitte mit jeweils mehreren Eingaben. Wenden Sie also ein gutes Design an und machen Sie jeden Abschnitt zu einer eigenen Komponente, indem Sie Komponenten für das Formular gruppieren Gruppen. Dies macht normalerweise eine Komponente für weniger als 10 Eingaben verantwortlich, und plötzlich ist Ihre Informationsarchitektur viel sinnvoller. Das Senden des Formulars als Browser-Aktion sieht natürlich nur "Ihr Formular" und sendet alles auf einmal. Sauberes, zielgerichtetes UI-Design.
Mike 'Pomax' Kamermans
2
Danke für die Kommentare. Ich habe jedoch festgestellt, dass die Statusverknüpfung ab React v15 veraltet ist.
JoeTidee
3
@JasonChing, dann haben Sie einfach potenzielle Fehler in Ihren Code eingebaut. React ist keine "Be All, End All" -Lösung für Webseiten, sondern ein Framework zum Erstellen von Schnittstellen. Es ist nachträglich für die Statusverwaltung und das tatsächliche Rendern der Benutzeroberfläche verantwortlich (Ihre Benutzer interagieren nicht mit dem DOM, sondern mit ihnen Reagieren. Die DOM-Updates sind einfach ein asynchroner (aber unglaublich schneller) letzter Schritt, damit die Benutzeroberfläche den Status visuell widerspiegelt. Wenn Sie dies umgehen möchten, ist die wichtigere Frage: Warum verwenden Sie React? Weil das beste Zeichen, das Sie falsch verwenden, die Kombination von React und jQuery ist.
Mike 'Pomax' Kamermans
17

Es ist gelungen, den Eingabefeldwert auf folgende Weise abzurufen:

import React, { Component } from 'react';

class App extends Component {

constructor(props){
super(props);

this.state = {
  username : ''
}

this.updateInput = this.updateInput.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}


updateInput(event){
this.setState({username : event.target.value})
}


handleSubmit(){
console.log('Your input value is: ' + this.state.username)
//Send state to the server code
}



render(){
return (
    <div>
    <input type="text" onChange={this.updateInput}></input>
    <input type="submit" onClick={this.handleSubmit} ></input>
    </div>
  );
}
} 

//output
//Your input value is: x
Hugo Wesley
quelle
Warum "setState" verwenden? Dies beinhaltet ein erneutes Rendern, nicht wahr?
Luca Davanzo
15

In Reaktion 16 benutze ich

<Input id="number" 
       type="time" 
       onChange={(evt) => { console.log(evt.target.value); }} />
Pyae Sone
quelle
funktioniert nicht, wenn das Feld bei Altersbelastung automatisch
ausgefüllt wurde
4

Dies gelang mir, indem ich das "this" an die Funktion updateInputValue (evt) mit band

this.updateInputValue = this.updateInputValue.bind (this);

Der Eingabewert = {this.state.inputValue} ... erwies sich jedoch als keine gute Idee.

Hier ist der vollständige Code in babel ES6:

class InputField extends React.Component{


  constructor(props){
   super(props);
   //this.state={inputfield: "no value"};   
   this.handleClick = this.handleClick.bind(this);
   this.updateInputValue = this.updateInputValue.bind(this);
  }

  handleClick(){
   console.log("trying to add picture url");
   console.log("value of input field : "+this.state.inputfield);

  }

  updateInputValue(evt){
    //console.log("input field updated with "+evt.target.value);
    this.state={inputfield: evt.target.value};   

  }

  render(){
    var r; 
    r=<div><input type="text" id="addpixinputfield" 
            onChange={this.updateInputValue} />
      <input type="button" value="add" id="addpix" onClick={this.handleClick}/>
      </div>;    
    return r;
   }
}
Matthias Liszt
quelle
2

Ihr Fehler ist darauf zurückzuführen, dass Sie class verwenden. Wenn Sie class verwenden, müssen wir die Funktionen mit This verknüpfen, damit dies gut funktioniert. Trotzdem gibt es viele Tutorials, warum wir "dies" tun sollten und was "dies" in Javascript tun soll.

Wenn Sie Ihren Submit-Button korrigieren, sollte es funktionieren:

<button type="button" onClick={this.onSubmit.bind(this)} className="btn">Save</button>

und auch wenn Sie den Wert dieser Eingabe in der Konsole anzeigen möchten, sollten Sie var title = this.title.value verwenden;

Soroush Bk
quelle
2
Dieser Link könnte hilfreich sein, wenn Sie mehr über "this"
Soroush Bk
1
// On the state
constructor() {
  this.state = {
   email: ''
 }
}

// Input view ( always check if property is available in state {this.state.email ? this.state.email : ''}

<Input 
  value={this.state.email ? this.state.email : ''} 
  onChange={event => this.setState({ email: event.target.value)}
  type="text" 
  name="emailAddress" 
  placeholder="[email protected]" />
Kidali Kevin
quelle
Während Ihre Antwort für die Frage gut sein könnte, ist es immer besser, eine Erklärung hinzuzufügen. Bitte nehmen Sie sich 2 Minuten Zeit, um es hinzuzufügen. Dies wird Ihre Antwort auch für zukünftige Benutzer verbessern.
DaFois
Klar, das werde ich machen.
Kidali Kevin
1

Geben Sie dem <input>eine eindeutige ID

<input id='title' ...>

Verwenden Sie dann die Standard-Web-API, um im DOM darauf zu verweisen

const title = document.getElementById('title').value

Sie müssen den Reaktionsstatus nicht bei jedem Tastendruck ständig aktualisieren. Holen Sie sich einfach den Wert, wenn es erforderlich ist.

Brent Washburne
quelle
0

Sie können einen Eingabewert erhalten, ohne die Funktion 'onChange' hinzuzufügen.

Fügen Sie dem Eingabeelement einfach ein 'ref attr:

Verwenden Sie dann this.refs, um den Eingabewert abzurufen, wenn Sie ihn benötigen.

E1ad
quelle
3
Dies wird nicht mehr empfohlen.
JoeTidee
1
Sie können sie verwenden, es wird jedoch empfohlen, den Datenfluss mithilfe von Requisiten und Rückrufen in eine Richtung zu halten.
JoeTidee
Es wäre gut, ein Beispiel für das korrekte Hinzufügen von Refs hinzuzufügen, dh einen Ref-Rückruf anstelle einer Legacy-Zeichenfolge zu verwenden.
JoeTidee
0

Ändern Sie Ihre Referenz in: ref='title'und löschen Sie name='title' dann Löschen var title = this.titleund schreiben Sie:

console.log(this.refs.title.value)

Auch sollten Sie hinzufügen .bind(this)zuthis.onSubmit

(Es hat in meinem Fall funktioniert, was ziemlich ähnlich war, aber anstatt onClickich hatte onSubmit={...}und es wurde in Form gebracht ( <form onSubmit={...} ></form>))

Katarzyna Wrońska
quelle
0

Wenn Sie eine Klassenkomponente verwenden, sind es nur 3 Schritte. Zuerst müssen Sie den Status für Ihre Eingabe deklarieren, z. B. this.state = {name: ''} . Zweitens müssen Sie eine Funktion zum Festlegen des Status schreiben, wenn er sich im folgenden Beispiel ändert: setName (), und schließlich müssen Sie die Eingabe jsx schreiben, zum Beispiel <input value = {this.name} onChange = {this.setName} />

import React, { Component } from 'react'

export class InputComponents extends Component {
    constructor(props) {
        super(props)

        this.state = {
             name:'',
             agree:false
        }
        this.setName = this.setName.bind(this);
        this.setAgree=this.setAgree.bind(this);
    }

    setName(e){
        e.preventDefault();
        console.log(e.target.value);
        this.setState({
            name:e.target.value
        })
    }
    setAgree(){
        this.setState({
            agree: !this.state.agree
        }, function (){
            console.log(this.state.agree);
        })
    }
    render() {
        return (
            <div>
                <input type="checkbox" checked={this.state.agree} onChange={this.setAgree}></input>
                < input value={this.state.name} onChange = {this.setName}/>
            </div>
        )
    }
}

export default InputComponents
Herr
quelle
0
export default class MyComponent extends React.Component {

onSubmit(e) {
    e.preventDefault();
    var title = this.title.value; //added .value
    console.log(title);
}

render(){
    return (
        ...
        <form className="form-horizontal">
            ...
            <input type="text" className="form-control" ref={input => this.title = input} name="title" />
            ...
        </form>
        ...
        <button type="button" onClick={this.onSubmit} className="btn">Save</button>
        ...
    );
}

};
Pranav Agarwal
quelle
0

Verwenden unkontrollierter Felder:

export default class MyComponent extends React.Component {

    onSubmit(e) {
        e.preventDefault();
        console.log(e.target.neededField.value);
    }

    render(){
        return (
            ...
            <form onSubmit={this.onSubmit} className="form-horizontal">
                ...
                <input type="text" name="neededField" className="form-control" ref={(c) => this.title = c} name="title" />
                ...
            </form>
            ...
            <button type="button" className="btn">Save</button>
            ...
        );
    }

};
Georg
quelle