it-swarm.com.de

Reagieren - Ändern einer unkontrollierten Eingabe

Ich habe eine einfache Reaktionskomponente mit der Form, von der ich glaube, dass sie eine kontrollierte Eingabe hat:

import React from 'react';

export default class MyForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    render() {
        return (
            <form className="add-support-staff-form">
                <input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
            </form>
        )
    }

    onFieldChange(fieldName) {
        return function (event) {
            this.setState({[fieldName]: event.target.value});
        }
    }
}

export default MyForm;

Wenn ich meine Anwendung starte, erhalte ich die folgende Warnung:

Warnung: MyForm ändert eine unkontrollierte Eingabe des Texttyps in kontrolliert. Eingabeelemente sollten nicht von unkontrolliert zu .__ wechseln. gesteuert (oder umgekehrt). Entscheiden Sie sich für ein kontrolliertes oder unkontrolliertes Eingabeelement für die Lebensdauer der Komponente

Ich glaube, dass meine Eingabe kontrolliert wird, da sie einen Wert hat. Ich frage mich, was mache ich falsch?

Ich verwende React 15.1.0

183
alexs333

Ich glaube, dass meine Eingabe kontrolliert wird, da sie einen Wert hat.

Damit ein Eingang gesteuert werden kann, muss sein Wert dem einer Zustandsvariablen entsprechen.

Diese Bedingung ist in Ihrem Beispiel anfangs nicht erfüllt, da this.state.name anfangs nicht festgelegt ist. Daher ist die Eingabe zunächst unkontrolliert. Sobald der onChange-Handler zum ersten Mal ausgelöst wird, wird this.state.name gesetzt. Zu diesem Zeitpunkt ist die obige Bedingung erfüllt und es wird davon ausgegangen, dass die Eingabe gesteuert wird. Dieser Übergang von unkontrolliert zu gesteuert führt zu dem oben gezeigten Fehler.

Durch Initialisierung von this.state.name im Konstruktor:

z.B.

this.state = { name: '' };

die Eingabe wird von Anfang an kontrolliert und das Problem behoben. Siehe Reagieren Sie kontrollierte Komponenten für weitere Beispiele.

Unabhängig von diesem Fehler sollten Sie nur einen Standardexport haben. Ihr Code oben hat zwei.

278
fvgs

Wenn Sie Ihre Komponente zum ersten Mal rendern, wird this.state.name nicht festgelegt, daher wird undefined ausgewertet, und Sie übergeben value={undefined} an Ihre input.

Wenn ReactDOM prüft, ob ein Feld kontrolliert wird, prüft , ob value != null (beachten Sie, dass es != und nicht !== ist), und dass undefined == null in JavaScript dies nicht kontrolliert.

Wenn also onFieldChange() aufgerufen wird, this.state.name auf einen Stringwert gesetzt ist, wird Ihre Eingabe nicht mehr unkontrolliert, sondern wird kontrolliert.

Wenn Sie in Ihrem Konstruktor this.state = {name: ''} ausführen, hat '' != null für Ihre Eingabe die ganze Zeit einen Wert, und diese Nachricht wird ausgeblendet.

84
Adam Brenecki

Ein anderer Ansatz könnte darin bestehen, den Standardwert in Ihrer Eingabe festzulegen:

 <input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>
28
JpCrow

Ich weiß, dass andere dies bereits beantwortet haben. Aber einer der sehr wichtigen Faktoren, der anderen Menschen helfen kann, die ein ähnliches Problem haben:

Sie müssen einen onChange-Handler in Ihrem Eingabefeld haben (z. B. textField, Kontrollkästchen, Radio usw.). Und behandeln Sie Aktivitäten immer über den onChange-Handler, z. 

<input ... onChange={ this.myChangeHandler} ... />

wenn Sie mit checkbox arbeiten, müssen Sie möglicherweise den checked-Status mit !! wie folgt behandeln:

<input type="checkbox" checked={!!this.state.someValue} onChange={.....} >

Referenz: https://github.com/facebook/react/issues/6779#issuecomment-326314716

6
Muhammad Hannan

Ein möglicher Nachteil beim Setzen des Feldwerts auf "" (leere Zeichenfolge) im Konstruktor ist, wenn das Feld ein optionales Feld ist und nicht bearbeitet wird. Wenn Sie vor dem Hochladen Ihres Formulars nicht etwas massieren, wird das Feld in Ihrem Datenspeicher als leere Zeichenfolge anstelle von NULL gespeichert. 

Diese Alternative vermeidet leere Zeichenfolgen:

constructor(props) {
    super(props);
    this.state = {
        name: null
    }
}

... 

<input name="name" type="text" value={this.state.name || ''}/>
4
Greg R Taylor

Wenn Sie in Ihrer EingabeonChange={this.onFieldChange('name').bind(this)}verwenden, müssen Sie Ihren Status-Leerstring als Eigenschaftswertfeld deklarieren.

falsche Weise:

this.state ={
       fields: {},
       errors: {},
       disabled : false
    }

der richtige Weg:

this.state ={
       fields: {
         name:'',
         email: '',
         message: ''
       },
       errors: {},
       disabled : false
    }
3
KARTHIKEYAN.A

Wenn die Requisiten Ihrer Komponente als Status übergeben wurden, geben Sie einen Standardwert für Ihre Eingabetags ein

<input type="text" placeholder={object.property} value={object.property ? object.property : ""}>
2
Emperor Krauser

Ein Update dafür. Verwenden Sie für React Hooks const [name, setName] = useState ("")

2
Jordan Mullen

Setzen Sie einen Wert auf 'name' im ursprünglichen Zustand.

this.state={ name:''};

1

In meinem Fall hat mir etwas wirklich Triviales gefehlt. 

<input value={state.myObject.inputValue} />

Mein Zustand war der folgende, als ich die Warnung erhielt:

state = {
   myObject: undefined
}

Durch das Wechseln meines Zustands zum Verweis der Eingabe meines Wertes wurde mein Problem gelöst:

state = {
   myObject: {
      inputValue: ''
   }
}

Eine einfache Lösung für dieses Problem besteht darin, standardmäßig einen leeren Wert festzulegen:

<input name='myInput' value={this.state.myInput || ''} onChange={this.handleChange} />
0

Dies geschieht im Allgemeinen nur dann, wenn Sie den Wert des Felds beim Start der Anwendung nicht steuern und nachdem ein Ereignis oder eine Funktion ausgelöst oder der Status geändert wurde, versuchen Sie nun, den Wert im Eingabefeld zu steuern. 

Dieser Übergang, die Kontrolle über die Eingabe und dann die Kontrolle über sie zu haben, führt dazu, dass das Problem überhaupt erst auftritt.

Dies lässt sich am besten vermeiden, indem Sie im Konstruktor der Komponente einen bestimmten Wert für die Eingabe deklarieren. Damit das Eingabeelement einen Wert vom Start der Anwendung hat. 

0