Eingabefeld Text eingeben kann nicht eingegeben werden

111

Ich versuche mein erstes Stück React.js und bin schon früh ratlos ... Ich habe den folgenden Code, in den ein Suchformular gerendert wird <div id="search"></div>. Das Eingeben in das Suchfeld bewirkt jedoch nichts.

Vermutlich fehlt etwas, wenn man die Requisiten passiert und auf und ab geht, und dies scheint ein häufiges Problem zu sein. Aber ich bin ratlos - ich kann nicht sehen, was fehlt.

var SearchFacet = React.createClass({
  handleChange: function() {
    this.props.onUserInput(
      this.refs.searchStringInput.value
    )
  },
  render: function() {
    return (
      <div>
        Search for:
        <input
          type="text"
          value={this.props.searchString}
          ref="searchStringInput"
          onchange={this.handleChange} />
      </div>
    );
  }
});

var SearchTool = React.createClass({
  render: function() {
    return (
      <form>
        <SearchFacet 
          searchString={this.props.searchString}
          onUserInput={this.props.onUserInput}
         />
        <button>Search</button>
      </form>
    );
  }
});

var Searcher = React.createClass({
  getInitialState: function() {
    return {
      searchString: ''
    }
  },

  handleUserInput: function(searchString) {
    this.setState({
      searchString: searchString
    })
  },

  render: function() {
    return (
      <div>
        <SearchTool 
          searchString={this.state.searchString}
          onUserInput={this.handleUserInput}
        />
      </div>
    );
  }
});

ReactDOM.render(
  <Searcher />,
  document.getElementById('searcher')
);

(Irgendwann werde ich andere Arten von haben, SearchFacet*aber ich versuche nur, diese zum Laufen zu bringen.)

Phil Gyford
quelle
Versuchen Sie die Protokollierung, thiswenn Sie das Textfeld eingeben. Es könnte sein, dass dies thisnicht Searchermehr die Komponente ist.
FaureHu
Danke FaureHu - Protokollierung thisan welcher Stelle im Code? Der Versuch, sich anzumelden Searcher.handleUserInput()oder SearchFacet.handleChange()macht nichts.
Phil Gyford
Sie können meine Antwort auf ähnliche Fragen sehen. Sie können detaillierte Erklärung finden: stackoverflow.com/questions/34713718/…
prudhvi seeramreddi

Antworten:

78

Sie haben Ihre onchangeRequisite nicht richtig in der input. Es muss onChangein JSX sein.

<input
  type="text"
  value={this.props.searchString}
  ref="searchStringInput"
  onchange={this.handleChange} <--[should be onChange]
/>  

Das Thema, eine valueRequisite an eine zu übergeben <input>und dann den als Reaktion auf Benutzerinteraktion mit einem onChangeHandler übergebenen Wert irgendwie zu ändern, wird in den Dokumenten ziemlich gut berücksichtigt .

Sie beziehen sich auf Eingaben wie gesteuerte Komponenten und auf Eingaben, mit denen das DOM stattdessen den Wert der Eingabe und nachfolgende Änderungen des Benutzers nativ als nicht kontrollierte Komponenten verarbeiten kann .

Immer wenn Sie die valueStütze von a auf eine inputVariable setzen, haben Sie eine kontrollierte Komponente . Dies bedeutet, dass Sie den Wert der Variablen auf programmatische Weise ändern müssen. Andernfalls enthält die Eingabe immer diesen Wert und ändert sich auch während der Eingabe nie. Das native Verhalten der Eingabe, um ihren Wert beim Tippen zu aktualisieren, wird überschrieben von Hier reagieren.

Sie nehmen diese Variable also korrekt aus dem Status und haben einen Handler, um den Status zu aktualisieren. Das Problem war, dass Sie den Handler nie aufgerufen haben onchangeund nicht den richtigen, onChangeder beim Aufrufen valueder Eingabe nie aktualisiert wurde. Wenn Sie das tun verwenden onChangedie Handler wird aufgerufen, das value wird aktualisiert , wenn Sie schreiben, und sehen Sie Ihre Änderungen.

davnicwil
quelle
200

Wenn value={whatever}Sie verwenden, wird das Eingabefeld nicht eingegeben. Sie sollten verwenden defaultValue="Hello!".

Siehe https://facebook.github.io/react/docs/uncontrolled-components.html#default-values

Auch sollte das onchangesein, onChangewie @davnicwil hervorhebt.

Ivan
quelle
2
In meiner Anforderung wollte ich ein Feld mit Eingabefreigabe eingeben und es muss auf den Standardwert gesetzt werden, der von einer Statusvariablen stammt. Das defaultValue-Attribut war in Ordnung, aber es gibt ein Problem beim Aktualisieren des Standardwerts gemäß Statusänderungen. Gibt es eine Möglichkeit, die Änderung des Standardwerts zu erzwingen?
Semira
1
Sie sollten dieses Problem als eine weitere Frage in Stackoverflow veröffentlichen.
Ivan
1
@GeoffreyHale Ich bin mir nicht ganz sicher, was du damit meinst, wie irreführend es ist. In diesem Beispiel wird der Status nicht verwendet: codepen.io/anon/pen/BQJZwr?editors=0010 . Oder dieses, das tut: codepen.io/anon/pen/JbMJMX?editors=0010
Ivan
4
@ Ivan Du hast recht, beide sind unveränderlich: value={whatever}und value={this.state.myvalue}. Ich hätte stattdessen diese Klarstellung machen sollen : Die Verwendung von onChange={this.handleChange}und so etwas handleChange: function(e) { var newState = {}; newState[e.target.name] = e.target.value; this.setState(newState); },macht Felder wieder veränderbar.
Geoffrey Hale
1
@Ivan Dieser hat mir nur geholfen. Vielen Dank, defaultValuerette meinen Tag.
Code Cooker
10

Dies kann daran liegen, dass die Funktion onChange nicht den richtigen Wert aktualisiert, der in der Eingabe angegeben ist.

Beispiel:

<input type="text" value={this.state.textValue} onChange = {this.changeText}></input>

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

Aktualisieren Sie in der Funktion onChange das angegebene Wertefeld.

Sunaina Kotekar
quelle
Danke, sehr hilfreich. Nur Ihre Antwort erklärt vollständig, wie Sie das Problem lösen können.
M3RS
Wo soll diese changeText-Funktion definiert werden?
Jitendra Pancholi
Wenn es sich um eine zustandslose Komponente innerhalb der Funktion und wenn es sich um eine Klassenkomponente handelt, innerhalb des Konstruktors.
Gal Grünfeld
Sie müssen this.state nicht in den setState schreiben. Wenn Sie nur textValue: event.target.value in setState schreiben, funktioniert es auch perfekt
Pardeep Sharma
4

Ich habe auch das gleiche Problem und in meinem Fall habe ich das Reduzierstück richtig eingespritzt, aber ich konnte immer noch kein Feld eingeben. Es stellt sich heraus, wenn Sie verwenden immutable, müssen Sie verwenden redux-form/immutable.

import {reducer as formReducer} from 'redux-form/immutable';
const reducer = combineReducers{

    form: formReducer
}
import {Field, reduxForm} from 'redux-form/immutable';
/* your component */

Beachten Sie, dass Ihr Status so sein sollte, dass state->formSie die Bibliothek explizit konfigurieren müssen. Außerdem sollte der Name für den Status lauten form. siehe dieses Problem

Seyed Jalal Hosseini
quelle
4

Für mich hat die folgende einfache Änderung perfekt funktioniert

<input type="text" 
        value={props.letter} 
        onChange={event => setTxtLetter(event.target.value)} /> {/* does not work */}

Ändern Sie ... value = {myPropVal} in ... defaultValue = {myPropVal}

<input type="text" 
        defaultValue={props.letter} 
        onChange={event => setTxtLetter(event.target.value)} /> {/* Works!! */}
Nelles
quelle
Das hat es für mich behoben. Danke!
Mikeym
Ich denke, onChange funktioniert nicht richtig, wenn es in Formik verwendet wird. Ich habe es auch versucht, aber es hat bei mir nicht funktioniert. Könnten Sie bitte hier einen Blick darauf werfen? stackoverflow.com/questions/61689720/…
a125
0

In einem Klassenkomponentenkontext ...

Wenn die changeHandler-Methode eine normale Funktion ist:

handleChange(e){
    this.setState({[e.target.name]:[e.target.value]});
}

es kann so verwendet werden ...onChange={(e)=>this.handleChange(e)}

<input type="text" name="any" value={this.state.any} onChange={(e)=>this.handleChange(e)}></input>

Wenn die changeHandler-Methode eine Pfeilfunktion ist:

handle = (e) =>{
        this.setState({[e.target.name]:[e.target.value]});
    }

es kann so verwendet werden ... onChange={this.handle}

 <input type="text" name="any2" value={this.state.any2} onChange={this.handle} ></input>

Und dies löste mein Problem "Eingabefeld kann nicht eingegeben werden".

Aditya Patnaik
quelle