it-swarm.com.de

Korrigieren Sie die Änderung von Zustandsfeldern in ReactJS

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

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

Ich befürchte, dass das Ändern des Arrays vor Ort mit Push Probleme verursachen kann - ist es sicher?

Die Alternative, eine Kopie des Arrays zu erstellen, und setStateing scheint verschwenderisch.

292
fadedbee

Die React docs sagt:

Behandle diesen Zustand so, als wäre er unveränderlich.

Ihre Push ändert den Status direkt und dies kann möglicherweise zu fehleranfälligem Code führen, auch wenn Sie den Status danach erneut "zurücksetzen". B. könnte es dazu führen, dass einige Lebenszyklusmethoden wie componentDidUpdate nicht ausgelöst werden.

In späteren React-Versionen wird empfohlen, die Funktion Updater zu verwenden, um Zustände zu ändern, um Race-Bedingungen zu verhindern:

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

Der Speicher "Verschwendung" ist im Vergleich zu den Fehlern, die bei der Verwendung von nicht standardmäßigen Zustandsänderungen auftreten könnten, kein Problem.

Alternative Syntax für frühere React-Versionen

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

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

In ES6 können Sie den Spread Operator verwenden:

this.setState({
  arrayvar: [...this.state.arrayvar, newelement]
})
581
David Hellsing

Am einfachsten, wenn Sie ES6 verwenden.

initialArray = [1, 2, 3];

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

Neues Array wird [1,2,3,4] sein 

aktualisieren Sie Ihren Status in React

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

Erfahren Sie mehr über die Zerstörung von Arrays

110
StateLess

Der einfachste Weg mit ES6:

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

React kann Batch-Aktualisierungen durchführen. Daher ist es der richtige Ansatz, setState mit einer Funktion zu versehen, 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) => {
    state.array = state.array.concat([4]);
    return state;
});

Das Folgende zeigt, was https://jsbin.com/mofekakuqi/7/edit?js,output als Beispiel dafür ist, was passiert, wenn Sie es falsch verstehen.

Beim Aufruf von setTimeout () werden drei Elemente korrekt hinzugefügt, da React nicht innerhalb eines setTimeout-Rückrufs Aktualisierungen erstellt (siehe https://groups.google.com/d/msg/reactjs/G6pljvpTGX0/0ihYw2zK9dEJ ).

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

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 <li key={i}>{item}</li>
    });
       console.log(this.state);

    return (
      <div className='list'>
        <button onClick={this.addSome}>add three</button>
        <button onClick={this.addSomeFixed}>add three (fixed)</button>
        <ul>
        {list}
        </ul>
      </div>
    );
  }
};


ReactDOM.render(<List />, document.getElementById('app'));
21
NealeU

Wie @nilgun im Kommentar erwähnt, können Sie die Hilfsmittel reagieren Unveränderlichkeit verwenden. Ich fand das super nützlich.

Aus den Dokumenten:

Einfacher Push

var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$Push: [4]}); // => [1, 2, 3, 4]

initialArray ist immer noch [1, 2, 3].

17
Clarkie

Sie können diese Methode verwenden : [Array Destructuring]

this.setState(prevState => {
    return {
        arrayData: [...prevState.arrayData, newElement]
    }
});

Reagieren Sie auf Dokumente: Mutieren Sie den this.state niemals direkt. Wie David Hellsing in seiner Antwort erklärt : Wenn Sie danach setState () aufrufen, kann dies die von Ihnen vorgenommene Mutation ersetzen. Behandle this.state als wäre es unveränderlich.

1
Hsaidooo
this.setState({
  arrayvar: [...this.state.arrayvar, ...newelement]
})
0
M.Samiei