2015-09-05 11 views
59

Ich habe Probleme mit einem Reagieren Formular und Verwalten des Status ordnungsgemäß. Ich habe ein Zeiteingabefeld in einer Form (in einem modalen). Der Anfangswert wird als eine Statusvariable in getInitialState festgelegt und von einer übergeordneten Komponente übergeben. Das funktioniert an sich gut.Aktualisierungszustand auf Requisiten ändern in React Form

Das Problem tritt auf, wenn ich den Standardwert start_time über die übergeordnete Komponente aktualisieren möchte. Das Update selbst passiert in der Elternkomponente durch . In meinem Formular ändert sich der Standardwert für start_time jedoch nie, da er nur einmal in getInitialState definiert wird.

Ich habe versucht, componentWillUpdate zu verwenden, um eine Zustandsänderung durch setState start_time: next_props.start_time zu zwingen, die tatsächlich funktionierte, sondern gab mir Uncaught RangeError: Maximum call stack size exceeded Fehler.

Also meine Frage ist, was ist die korrekte Art der Aktualisierung in diesem Fall? Denke ich irgendwie über das Falsche nach?

Aktuelle Code:

@ModalBody = React.createClass 
    getInitialState: -> 
    start_time: @props.start_time.format("HH:mm") 

    #works but takes long and causes: 
    #"Uncaught RangeError: Maximum call stack size exceeded" 
    componentWillUpdate: (next_props, next_state) -> 
    @setState(start_time: next_props.start_time.format("HH:mm")) 

    fieldChanged: (fieldName, event) -> 
    stateUpdate = {} 
    stateUpdate[fieldName] = event.target.value 
    @setState(stateUpdate) 

    render: -> 
    React.DOM.div 
     className: "modal-body" 
     React.DOM.form null, 
     React.createElement FormLabelInputField, 
      type: "time" 
      id: "start_time" 
      label_name: "Start Time" 
      value: @state.start_time 
      onChange: @fieldChanged.bind(null, "start_time”) 

@FormLabelInputField = React.createClass 
    render: -> 
    React.DOM.div 
     className: "form-group" 
     React.DOM.label 
     htmlFor: @props.id 
     @props.label_name + ": " 
     React.DOM.input 
     className: "form-control" 
     type: @props.type 
     id: @props.id 
     value: @props.value 
     onChange: @props.onChange 

Antwort

144

Wenn ich richtig verstehe, haben Sie eine übergeordnete Komponente, die start_time bis auf die ModalBody Komponente ist vorbei, die sie ihren eigenen Staat vergibt? Und Sie möchten diese Zeit von der übergeordneten Komponente und nicht von einer untergeordneten Komponente aktualisieren.

React has some tips on dealing with this scenario. (Hinweis, dies ist ein alter Artikel, der seither aus dem Internet entfernt wurde. Hier ist ein Link zum aktuellen doc on component props).

Die Verwendung von Requisiten zur Generierung von Zuständen in getInitialState führt häufig zur Duplizierung von "Quelle der Wahrheit", d. H. Wo die echten Daten sind. Dies liegt daran, dass getInitialState nur aufgerufen wird, wenn die Komponente zum ersten Mal erstellt wird.

Wenn möglich, Werte sofort berechnen, um sicherzustellen, dass sie später nicht mehr synchron sind und Wartungsprobleme verursachen.

Grundsätzlich, wenn Sie props zu einem Kind der zuweisen Mutter state die Render-Methode ist nicht immer auf prop Aktualisierung aufgerufen. Sie müssen es manuell aufrufen, indem Sie die Methode componentWillReceiveProps verwenden.

componentWillReceiveProps(nextProps) { 
    // You don't have to do this check first, but it can help prevent an unneeded render 
    if (nextProps.startTime !== this.state.startTime) { 
    this.setState({ startTime: nextProps.startTime }); 
    } 
} 
+1

danke. Es hilft mir viel – Sukanta

+0

Was, wenn Sie tun möchten "Und Sie möchten diese Zeit von der übergeordneten, nicht eine untergeordnete Komponente aktualisieren." umgekehrt? – ram4nd

+0

Dann wäre es eine einfache 'setState()' innerhalb der Kind-Komponente .. es sei denn, ich verpasse etwas. –

Verwandte Themen