setState vs replaceState in React.js

96

Ich bin neu in der React.js-Bibliothek und habe einige der Tutorials durchgesehen und bin auf Folgendes gestoßen:

  • this.setState
  • this.replaceState

Die Beschreibung ist nicht sehr klar (IMO).

setState is done to 'set' the state of a value, even if its already set 
in the 'getInitialState' function.

Ähnlich,

The replaceState() method is for when you want to clear out the values 
already in state, and add new ones.

Ich habe versucht, this.setState({data: someArray});gefolgt von this.replaceState({test: someArray});und dann console.logged sie und ich fand, dass statejetzt beide dataund hatte test.

Dann habe ich versucht, this.setState({data: someArray});gefolgt von this.setState({test: someArray});und dann console.logged sie und ich fand, dass statewieder beide dataund hatte test.

Was genau ist der Unterschied zwischen den beiden?

myusuf
quelle
1
Ihr erstes Beispiel ist ungenau. replaceState würde den vorherigen Status entfernen. Sie testen es wahrscheinlich falsch.
Brigand
1
Ich habe nicht nach Änderungen in einem Rückruf gesucht. Vielleicht ist das der Grund ...
Myusuf

Antworten:

138

Mit setStatedem aktuellen und dem vorherigen Status werden zusammengeführt. Mit replaceStatewird der aktuelle Status gelöscht und nur durch das ersetzt, was Sie bereitstellen. Wird normalerweise setStateverwendet, es sei denn, Sie müssen aus irgendeinem Grund wirklich Schlüssel entfernen. Das Setzen auf false / null ist jedoch normalerweise eine explizitere Taktik.

Während es möglich ist, könnte es sich ändern; replaceState verwendet derzeit das übergebene Objekt als Status, dh replaceState(x)und sobald es festgelegt ist this.state === x. Dies ist etwas leichter als setState, daher kann es als Optimierung verwendet werden, wenn Tausende von Komponenten häufig ihren Status festlegen.
Ich habe dies mit diesem Testfall behauptet .


Wenn Ihr aktueller Status ist {a: 1}und Sie anrufen this.setState({b: 2}); Wenn der Zustand angewendet wird, wird es sein {a: 1, b: 2}. Wenn Sie this.replaceState({b: 2})Ihren Staat anrufen würden, wäre {b: 2}.

Randnotiz: Der Status wird nicht sofort festgelegt, also nicht this.setState({b: 1}); console.log(this.state)beim Testen.

Räuber
quelle
1
Mir immer noch unklar. Können Sie ein Beispiel geben, bei dem die Verwendung eines über dem anderen das Ergebnis ändert, dh diese Zusammenführung, auf die Sie sich beziehen ...
Serj Sagan
1
Wie gibt es einen vorherigen und einen aktuellen Status, wie in, wie können wir darauf zugreifen? Außerdem habe ich ein Objekt übergeben, um den Status zu ersetzen, aber die vorherigen Statusdaten waren noch vorhanden.
Myusuf
1
Wann ist der Zustand festgelegt? Wie in wann kann ich console.log es und testen?
Myusuf
21
@ Myusuf.setState({...}, callback)
Brigand
46

Definition am Beispiel:

// let's say that this.state is {foo: 42}

this.setState({bar: 117})

// this.state is now {foo: 42, bar: 117}

this.setState({foo: 43})

// this.state is now {foo: 43, bar: 117}

this.replaceState({baz: "hello"})

// this.state. is now {baz: "hello"}

Beachten Sie dies jedoch in den Dokumenten :

setState () mutiert this.state nicht sofort, sondern erstellt einen ausstehenden Statusübergang. Der Zugriff auf this.state nach dem Aufrufen dieser Methode kann möglicherweise den vorhandenen Wert zurückgeben.

Gleiches gilt für replaceState()

Grav
quelle
14

Nach Ansicht der docs , replaceStatekönnte veraltet erhalten:

Diese Methode ist nicht für Komponenten der ES6-Klasse verfügbar, die React.Component erweitern. Es kann in einer zukünftigen Version von React vollständig entfernt werden.

Liran Brimer
quelle
Gibt es eine ähnliche Ersatzmethode?
zero_cool
1
Für eine "ähnliche" Methode könnten Sie this.setState verwenden ({alle: undefiniert, alt: undefiniert, Schlüssel: undefiniert, neu: Wert})
Wren
@ Wren, was ist das? Ist diese offizielle Signatur zum Zurücksetzen des Status?
Grün
Nein, es wird nur explizit der bereits vorhandene Status auf undefiniert gesetzt. Dies ist das Nettoergebnis von "replaceState" ohne alle vorhandenen Schlüssel.
Wren
2

Da dies replaceStatejetzt veraltet ist, finden Sie hier eine sehr einfache Problemumgehung. Obwohl es wahrscheinlich ziemlich selten ist, dass Sie darauf zurückgreifen würden / sollten.

So entfernen Sie den Status:

for (const old_key of Object.keys(this.state))
    this.setState({ [old_key]: undefined });

Oder alternativ, wenn Sie nicht mehrere Anrufe tätigen möchten setState

const new_state = {};
for (const old_key of Object.keys(this.state))
    new_state[old_key] = undefined;
this.setState(new_state);

Im Wesentlichen kehren jetzt alle vorherigen Schlüssel im Status zurück undefined, was sehr einfach mit einer ifAnweisung gefiltert werden kann :

if (this.state.some_old_key) {
    // work with key
} else {
    // key is undefined (has been removed)
}

if ( ! this.state.some_old_key) {
    // key is undefined (has been removed)
} else {
    // work with key
}

In JSX:

render() {
    return <div>
        { this.state.some_old_key ? "The state remains" : "The state is gone" }
    </div>
}

Um den Status zu "ersetzen", kombinieren Sie einfach das neue Statusobjekt mit einer Kopie des alten Status undefinedund legen Sie ihn als Status fest:

const new_state = {new_key1: "value1", new_key2: "value2"};
const state = this.state;

for (const old_key of Object.keys(state))
    state[old_key] = undefined;

for (const new_key of Object.keys(new_state))
    state[new_key] = new_state[new_key];

this.setState(state);
Stormpie
quelle