617 Stimmen

Korrekte Änderung der Zustandsarrays in React.js

Ich möchte ein Element am Ende eines state-Arrays hinzufügen. Ist dies der richtige Weg?

this.state.arrayvar.push(newelement);
this.setState({ arrayvar:this.state.arrayvar });

Ich mache mir Sorgen, dass das direkte Ändern des Arrays mit push Probleme verursachen könnte - ist das sicher?

Die Alternative, eine Kopie des Arrays zu erstellen und diese mit setState festzulegen, scheint verschwenderisch.

985voto

David Hellsing Punkte 101440

Die React-Dokumentation besagt:

Behandle this.state so, als ob es unveränderlich wäre.

Dein push wird den Status direkt ändern und das könnte potenziell zu fehleranfälligem Code führen, selbst wenn du den Status danach wieder "zurücksetzt". Zum Beispiel könnte es dazu führen, dass einige Lifecycle-Methoden wie componentDidUpdate nicht ausgelöst werden.

Der empfohlene Ansatz in späteren React-Versionen besteht darin, eine Updater-Funktion zu verwenden, um Rennbedingungen zu vermeiden, wenn Zustände geändert werden:

this.setState(prevState => ({
  arrayvar: [...prevState.arrayvar, neuelement]
}))

Der Speicher "verschwendung" ist im Vergleich zu den Fehlern, denen Sie bei der Verwendung von nicht-standardmäßigen Zustandsänderungen gegenüberstehen könnten, kein Problem.

Alternative Syntax für frühere React-Versionen

Sie können concat verwenden, um eine saubere Syntax zu erhalten, da es ein neues Array zurückgibt:

this.setState({ 
  arrayvar: this.state.arrayvar.concat([neuelement])
})

In ES6 können Sie den Spread Operator verwenden:

this.setState({
  arrayvar: [...this.state.arrayvar, neuelement]
})

167voto

StateLess Punkte 5034

Am einfachsten ist es, wenn du ES6 verwendest.

initialArray = [1, 2, 3];

newArray = [ ...initialArray, 4 ]; // --> [1,2,3,4]

Das neue Array wird [1,2,3,4] sein

um Ihren Zustand in React zu aktualisieren

this.setState({
  arrayvar:[...this.state.arrayvar, newelement]
});

Erfahren Sie mehr über Array-Destrukturierung

72voto

Ridd Punkte 7791

Auf einfachste Weise mit ES6:

this.setState(prevState => ({
    array: [...prevState.array, newElement]
}))

45voto

moshfiqrony Punkte 2827

Aktuell haben viele Menschen Probleme, den Zustand des useState-Hooks zu aktualisieren. Ich verwende diesen Ansatz, um ihn sicher zu aktualisieren, und möchte ihn hier teilen.

Das ist mein Zustand

const [state, setState] = useState([])

Angenommen, ich habe ein Objekt mit dem Namen obj1 und ich möchte es in meinen Zustand einfügen. Ich würde empfehlen, es so zu machen

setState(prevState => [...prevState, obj1])

Dies fügt das Objekt sicher am Ende ein und sorgt gleichzeitig für die Konsistenz des Zustands

33voto

NealeU Punkte 1157

React kann Aktualisierungen zusammenfassen, daher ist der richtige Ansatz, setState eine Funktion zu übergeben, die die Aktualisierung durchführt.

Für das React-Update-Addon funktioniert folgendes zuverlässig:

this.setState( state => update(state, {array: {$push: [4]}}) );

oder für concat():

this.setState( state => ({
    array: state.array.concat([4])
}));

Im Folgenden wird gezeigt, was passiert, wenn Sie es falsch machen: https://jsbin.com/mofekakuqi/7/edit?js,output

Der Aufruf von setTimeout() fügt korrekt drei Elemente hinzu, da React innerhalb eines setTimeout-Callbacks keine Aktualisierungen zusammenfasst (siehe https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ).

Das fehlerhafte onClick fügt nur "Third" hinzu, aber der korrigierte fügt wie erwartet F, S und T hinzu.

class List extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      array: []
    }

    setTimeout(this.addSome, 500);
  }

  addSome = () => {
      this.setState(
        update(this.state, {array: {$push: ["First"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Second"]}}));
      this.setState(
        update(this.state, {array: {$push: ["Third"]}}));
    };

  addSomeFixed = () => {
      this.setState( state => 
        update(state, {array: {$push: ["F"]}}));
      this.setState( state => 
        update(state, {array: {$push: ["S"]}}));
      this.setState( state => 
        update(state, {array: {$push: ["T"]}}));
    };

  render() {

    const list = this.state.array.map((item, i) => {
      return {item}
    });
       console.log(this.state);

    return (

        add three
        add three (fixed)

        {list}

    );
  }
};

ReactDOM.render(, document.getElementById('app'));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X