Richtige Methode zum Verschieben in das Statusarray

122

Ich habe anscheinend Probleme, Daten in ein Statusarray zu verschieben. Ich versuche es so zu erreichen:

this.setState({ myArray: this.state.myArray.push('new value') })

Aber ich glaube, das ist falsch und verursacht Probleme mit der Veränderlichkeit?

Ilja
quelle

Antworten:

144

Array-Push gibt die Länge zurück

this.state.myArray.push('new value')Gibt die Länge des erweiterten Arrays anstelle des Arrays selbst zurück. Array.prototype.push () .

Ich denke, Sie erwarten, dass der zurückgegebene Wert das Array ist.

Unveränderlichkeit

Es scheint eher das Verhalten von React zu sein:

Mutieren Sie diesen Zustand NIEMALS direkt, da der anschließende Aufruf von setState () die von Ihnen vorgenommene Mutation ersetzen kann. Behandle diesen Zustand so, als wäre er unveränderlich. React.Component .

Ich denke, du würdest es so machen (nicht mit React vertraut):

var joined = this.state.myArray.concat('new value');
this.setState({ myArray: joined })
Márton Tamás
quelle
Wenn ich es tue, ist console.log(this.state.myArray)es immer einer dahinter. Irgendeine Idee warum?
Si8
@ Si8 Nun, ich benutze React leider nicht zu oft. In den Dokumenten heißt es jedoch: setState()Änderungen am Komponentenstatus in die Warteschlange stellen und React mitteilen, dass diese Komponente und ihre untergeordneten Komponenten mit dem aktualisierten Status neu gerendert werden müssen. Ich denke, es wird in diesem Moment direkt nach dem Einstellen einfach nicht aktualisiert. Könnten Sie bitte ein Codebeispiel posten, in dem wir sehen können, welchen Punkt Sie setzen und protokollieren, bitte?
Márton Tamás
Danke für die Antwort. Es ist asynchron und zeigt Ihnen die Änderungen nicht sofort an. SetState hat jedoch einen Rückruf, der den richtigen Wert anzeigt. Danke noch einmal.
Si8
w3schools.com/jsref/jsref_concat_array.asp concat verkettet zwei Arrays (nicht Array und String), .concat('new value'); sollte sein .concat(['new value']);
Manohar Reddy Poreddy
1
@ManoharReddyPoreddy Nicht-Array-Werte sind für die concat()Methode perfekt gültig . Siehe: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ( Arrays und / oder Werte, die zu einem neuen Array verkettet werden sollen. )
Márton Tamás
176

Mit es6 geht es folgendermaßen:

this.setState({ myArray: [...this.state.myArray, 'new value'] }) //simple value
this.setState({ myArray: [...this.state.myArray, ...[1,2,3] ] }) //another array

Syntax verbreiten

Aliaksandr Sushkevich
quelle
1
Ich habe das gleiche getan, es gibt zwei Fälle, in denen myArray Werte haben kann und nicht. Wenn es also bereits Werte hat, funktioniert es einwandfrei. Aber in keinen Daten ... aktualisiert es den Status nicht mit 'neuem Wert'. Irgendeine Lösung?
Krina Soni
Es sollte mit allen Arrays funktionieren, egal ob es Werte hat oder nicht, es wird sowieso zerstört. Vielleicht stimmt an einem anderen Ort etwas nicht. Könnten Sie bitte ein Beispiel für Ihren Code zeigen?
Aliaksandr Sushkevich
Hallo Bitte beziehen Sie sich auf meinen Kommentar unter @Tamas Antwort. Es war nur ein Beispiel in der Konsole. Ich habe versucht, mit myArray: [... this.state.myArray, 'neuer Wert'] mein Statusarray zu aktualisieren. Es enthält jedoch nur den letzten Wert. Können Sie mir bitte die Lösung mitteilen?
Johncy
@Johncy Ich bin mir nicht sicher, ob Ihr Problem mit dieser Frage zusammenhängt. Versuchen Sie, eine separate Frage zu stellen und das erwartete Verhalten zu beschreiben. Ich werde versuchen, Ihnen zu helfen.
Aliaksandr Sushkevich
5
In den React-Dokumenten heißt es: "Da this.propsund this.statekönnen asynchron aktualisiert werden, sollten Sie sich bei der Berechnung des nächsten Status nicht auf deren Werte verlassen." Wenn Sie ein Array ändern, da das Array bereits als Eigenschaft von existiert this.stateund Sie auf seinen Wert verweisen müssen, um einen neuen Wert festzulegen, sollten Sie die Form verwenden setState(), die eine Funktion mit dem vorherigen Status als Argument akzeptiert. Beispiel: this.setState(prevState => ({ myArray: [...this.state.myArray, 'new value'] }));Siehe: reactjs.org/docs/…
Bungle
103

Nie empfohlen, den Staat direkt zu mutieren.

In späteren React-Versionen wird empfohlen, beim Ändern von Status eine Updater-Funktion zu verwenden, um Rennbedingungen zu vermeiden:

Schieben Sie die Zeichenfolge an das Ende des Arrays

this.setState(prevState => ({
  myArray: [...prevState.myArray, "new value"]
}))

Schieben Sie den String an den Anfang des Arrays

this.setState(prevState => ({
  myArray: ["new value", ...prevState.myArray]
}))

Objekt an das Ende des Arrays schieben

this.setState(prevState => ({
  myArray: [...prevState.myArray, {"name": "object"}]
}))

Objekt an den Anfang des Arrays schieben

this.setState(prevState => ({
  myArray: [ {"name": "object"}, ...prevState.myArray]
}))
Hemadri Dasari
quelle
1
Ich habe diese Antwort benutzt. Es funktioniert auch für das Voranstellen in das Array:this.setState((prevState) => ({ myArray: [values, ...prevState.myArray], }));
Gus
1
Dies ist ein viel besserer Ansatz als die akzeptierte Antwort und entspricht den Empfehlungen der React-Dokumentation.
Ian J Miller
2
Definitiv + 1, da die anderen Antworten nicht den neuesten Richtlinien für die Verwendung von Rückrufen entsprechen, wenn der Status mit sich selbst mutiert.
Matt Fletcher
Wie füge ich ein weiteres Array-Objekt zum Status-Array hinzu?
Chandni
14

Sie sollten den Status überhaupt nicht betreiben. Zumindest nicht direkt. Wenn Sie Ihr Array aktualisieren möchten, sollten Sie Folgendes tun.

var newStateArray = this.state.myArray.slice();
newStateArray.push('new value');
this.setState(myArray: newStateArray);

Es ist nicht wünschenswert, direkt am Statusobjekt zu arbeiten. Sie können sich auch die Unveränderlichkeitshilfen von React ansehen.

https://facebook.github.io/react/docs/update.html

Christoph
quelle
5
Ich glaube, diese Antwort ist die richtige, obwohl ich gerne gewusst hätte, warum wir nicht mit dem Staat operieren können, dh warum es nicht wünschenswert ist. Nach einigem Graben fand ich das folgende React-Tutorial - Warum Unveränderlichkeit wichtig ist , das dazu beitrug , die fehlenden Informationen zu ergänzen, und das Tutorial verwendet auch .slice(), um ein neues Array zu erstellen und Unveränderlichkeit zu bewahren. Danke für die Hilfe.
BebopSong
11

Mit der .concatMethode können Sie eine Kopie Ihres Arrays mit neuen Daten erstellen:

this.setState({ myArray: this.state.myArray.concat('new value') })

Aber Vorsicht vor dem besonderen Verhalten der .concatMethode beim Übergeben von Arrays - [1, 2].concat(['foo', 3], 'bar')wird dazu führen [1, 2, 'foo', 3, 'bar'].

Ginden
quelle
1

Dieser Code funktioniert für mich:

fetch('http://localhost:8080')
  .then(response => response.json())
  .then(json => {
  this.setState({mystate: this.state.mystate.push.apply(this.state.mystate, json)})
})
Hamid Hosseinpour
quelle
3
Willkommen bei Stack Overflow! Bitte antworten Sie nicht nur mit dem Quellcode. Versuchen Sie, eine schöne Beschreibung der Funktionsweise Ihrer Lösung zu geben. Siehe: Wie schreibe ich eine gute Antwort? . Danke
sɐunıɔ ןɐ qɐp
Ich habe es versucht, aber ohne Erfolg. Hier ist mein Codefetch(`api.openweathermap.org/data/2.5/forecast?q=${this.searchBox.value + KEY} `) .then( response => response.json() ) .then( data => { this.setState({ reports: this.state.reports.push.apply(this.state.reports, data.list)}); });
Henrie
und ich initialisierte zuerst Zustand als leeres Array, dh this.state = { reports=[] }... bitte ich möchte wissen, was ich falsch mache
henrie
@ Hamid Hosseinpour
Henrie
1

React-Native

Wenn Sie auch möchten, dass Ihre Benutzeroberfläche (dh Ihre FlatList) auf dem neuesten Stand ist, verwenden Sie PrevState: Wenn der Benutzer im folgenden Beispiel auf die Schaltfläche klickt, wird der Liste ein neues Objekt hinzugefügt (sowohl im Modell als auch in der Benutzeroberfläche )

data: ['shopping','reading'] // declared in constructor
onPress={() => {this.setState((prevState, props) => {
return {data: [new obj].concat(prevState.data) };
})}}. 
Mahgol Fa
quelle
0

Auf folgende Weise können wir die Objekte überprüfen und aktualisieren

this.setState(prevState => ({
    Chart: this.state.Chart.length !== 0 ? [...prevState.Chart,data[data.length - 1]] : data
}));
KARTHIKEYAN.A
quelle
0

Hier können Sie das Objekt nicht in ein Statusarray wie dieses verschieben. Sie können wie gewohnt im normalen Array pushen. Hier müssen Sie den Zustand einstellen,

this.setState({ 
     myArray: [...this.state.myArray, 'new value'] 
})
Sachin Muthumala
quelle
-1

Wenn Sie nur versuchen, den Status so zu aktualisieren

   handleClick() {
        this.setState(
{myprop: this.state.myprop +1}
        })
    }

Betrachten Sie diesen Ansatz

   handleClick() {
        this.setState(prevState => {
            return {
                count: prevState.count + 1
            }
        })
    }

Grundsätzlich schreibt prevState this.state für uns.

Herr niemand
quelle