Frage Aktualisierungsstatus auf Requisiten ändert sich in React Form


Ich habe Probleme mit einem React-Formular und ordne den Zustand richtig an. Ich habe ein Zeiteingabefeld in einer Form (in einem modalen). Der Anfangswert wird als Statusvariable in eingestellt getInitialStateund wird von einer übergeordneten Komponente übergeben. Das funktioniert an sich gut.

Das Problem tritt auf, wenn ich den Standardwert start_time über die übergeordnete Komponente aktualisieren möchte. Das Update selbst findet in der übergeordneten Komponente statt setState start_time: new_time. In meinem Formular ändert sich der Standardwert start_time jedoch nie, da er nur einmal definiert wird getInitialState.

Ich habe versucht zu verwenden componentWillUpdate eine Zustandsänderung erzwingen setState start_time: next_props.start_time, die tatsächlich funktioniert hat, aber 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?

Aktueller 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

75
2017-09-05 14:39


Ursprung


Antworten:


Wenn ich das richtig verstanden habe, haben Sie eine übergeordnete Komponente start_time runter zum ModalBody Komponente, die es seinem eigenen Staat zuweist? Und Sie möchten diese Zeit von der übergeordneten Komponente und nicht von einer untergeordneten Komponente aktualisieren.

Reactive enthält einige Tipps zum Umgang mit diesem Szenario. (Beachten Sie, dass dies ein alter Artikel ist, der inzwischen aus dem Internet entfernt wurde. Hier ist ein Link zum aktuellen doc auf Komponentenstützen).

Verwenden von Requisiten zum Generieren von Status in getInitialState führt häufig zur Verdoppelung der "Quelle der Wahrheit", d. h. wo die echten Daten sind. Das ist weil getInitialState wird nur aufgerufen, wenn die Komponente zum ersten Mal erstellt wird.

Wenn immer möglich, Werte sofort berechnen, um sicherzustellen, dass sie später nicht aus der Synchronisation geraten und Wartungsprobleme verursachen.

Grundsätzlich, wenn Sie Eltern zuweisen props zu einem Kind state Die Render-Methode wird nicht immer beim Prop-Update aufgerufen. Sie müssen es manuell aufrufen, indem Sie componentWillReceiveProps Methode.

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 });
  }
}

180
2017-09-05 15:29



Anscheinend ändern sich die Dinge .... getDerivedStateFromProps () ist jetzt die bevorzugte Funktion.

class Component extends React.Component {
  static getDerivedStateFromProps(props, current_state) {
    if (current_state.value !== props.value) {
      return {
        value: props.value,
        computed_prop: heavy_computation(props.value)
      }
    }
    return null
  }
}

(über code von danburzo @ github)


15
2018-04-17 01:02



Es gibt auch componentDidUpdate verfügbar.

Funktionsunterzeichnung:

componentDidUpdate(prevProps, prevState, snapshot)

Verwenden Sie dies als eine Gelegenheit, das DOM zu bearbeiten, wenn die Komponente aktualisiert wurde. Wird nicht initial aufgerufen render.

Sehen Wahrscheinlich brauchen Sie keinen abgeleiteten Staat Artikel, der Anti-Pattern für beide beschreibt componentDidUpdate und getDerivedStateFromProps. Ich fand es sehr nützlich.


1
2017-07-08 07:47