Haftungsausschluss
Verschachtelter Zustand in Reaktion ist falsches Design
Lesen Sie diese ausgezeichnete Antwort .
Begründung für diese Antwort:
Der setState von React ist nur ein integrierter Komfort, aber Sie werden schnell feststellen, dass er seine Grenzen hat. Durch die Verwendung benutzerdefinierter Eigenschaften und die intelligente Verwendung von forceUpdate erhalten Sie viel mehr. z.B:
class MyClass extends React.Component {
myState = someObject
inputValue = 42
...
MobX beispielsweise gibt den Status vollständig aus und verwendet benutzerdefinierte beobachtbare Eigenschaften.
Verwenden Sie in React-Komponenten Observables anstelle von state.
Es gibt eine andere kürzere Möglichkeit, verschachtelte Eigenschaften zu aktualisieren.
this.setState(state => {
state.nested.flag = false
state.another.deep.prop = true
return state
})
In einer Zeile
this.setState(state => (state.nested.flag = false, state))
Hinweis: Dies hier ist der Komma-Operator ~ MDN . Sehen Sie ihn hier in Aktion (Sandbox) .
Es ist ähnlich (obwohl dies die Zustandsreferenz nicht ändert)
this.state.nested.flag = false
this.forceUpdate()
Für den subtilen Unterschied in diesem Zusammenhang zwischen forceUpdate
und setState
siehe das verknüpfte Beispiel.
Natürlich missbraucht dies einige Kernprinzipien, da state
diese schreibgeschützt sein sollten, aber da Sie den alten Zustand sofort verwerfen und durch einen neuen Zustand ersetzen, ist dies völlig in Ordnung.
Warnung
Auch wenn die Komponente den Zustand enthält , wird aktualisiert und rerender richtig ( mit Ausnahme dieser Gotcha ) , werden die Requisiten nicht auf Kinder zu verbreiten (siehe Spymaster Kommentar unten) . Verwenden Sie diese Technik nur, wenn Sie wissen, was Sie tun.
Beispielsweise können Sie eine geänderte flache Requisite übergeben, die aktualisiert und problemlos übergeben werden kann.
render(
//some complex render with your nested state
<ChildComponent complexNestedProp={this.state.nested} pleaseRerender={Math.random()}/>
)
Jetzt, obwohl sich die Referenz für complexNestedProp nicht geändert hat ( shouldComponentUpdate )
this.props.complexNestedProp === nextProps.complexNestedProp
Die Komponente wird bei jeder Aktualisierung der übergeordneten Komponente erneut gerendert, was nach dem Aufruf this.setState
oder this.forceUpdate
im übergeordneten Element der Fall ist .
Auswirkungen der Mutation des Staates
Die Verwendung eines verschachtelten Status und die direkte Mutation des Status ist gefährlich, da verschiedene Objekte möglicherweise (absichtlich oder nicht) unterschiedliche (ältere) Verweise auf den Status enthalten und nicht unbedingt wissen, wann sie aktualisiert werden müssen (z. B. wenn sie verwendet werden PureComponent
oder wenn shouldComponentUpdate
sie für die Rückgabe implementiert sind false
) ODER sind soll alte Daten wie im folgenden Beispiel anzeigen.
Stellen Sie sich eine Zeitleiste vor, die historische Daten rendern soll. Wenn Sie die Daten unter der Hand mutieren, führt dies zu unerwartetem Verhalten, da auch vorherige Elemente geändert werden.
Wie auch immer, hier können Sie sehen, dass Nested PureChildClass
es nicht neu gerendert wurde, weil Requisiten sich nicht verbreiten konnten.