2015-08-27 14 views
12

Ich habe einen Zustand namens this.state.devices, die ein Array von device Objekte ist.ReactJS Aktualisieren eines einzelnen Objekts in einem Statusarray

sagen, dass ich eine Funktion haben hier

updateSomething: function (device) { 
    var devices = this.state.devices; 
    var index = devices.map(function(d){ 
     return d.id; 
    }).indexOf(device.id); 

    if (index !== -1) { 
     // do some stuff with device 
     devices[index] = device; 
     this.setState({devices:devices}); 
    } 
} 

Problem, dass this.updateSomething ist jedes Mal aufgerufen wird, wird das gesamte Array aktualisiert wird, und so die gesamte DOM neu gerendert wird. In meiner Situation verursacht dies, dass der Browser einfriert, da ich diese Funktion ziemlich jede Sekunde anrufe, und es gibt viele device Objekte. Bei jedem Anruf werden jedoch nur ein oder zwei dieser Geräte aktualisiert.

Was sind meine Optionen?

EDIT

In meine genaue Situation, ein device ist ein Objekt, das wie folgt definiert ist:

function Device(device) { 
    this.id = device.id; 
    // And other properties included 
} 

So ist jedes Element im Array von state.devices einem bestimmten Zeitpunkt dieser Device ist, dh irgendwo hätte ich:

Mein updat ed wie auf updateSomething beantworten, ich habe:

updateSomething: function (device) { 
    var devices = this.state.devices; 
    var index = devices.map(function(d){ 
     return d.id; 
    }).indexOf(device.id); 

    if (index !== -1) { 
     // do some stuff with device 
     var updatedDevices = update(devices[index], {someField: {$set: device.someField}}); 
     this.setState(updatedDevices); 
    } 
} 

Problem ist jetzt, dass ich einen Fehler, der den nicht definierten Wert von id nicht lesen, sagt kann, und aus dem function Device() kommt; es scheint, dass ein neuer new Device() aufgerufen wird und der device nicht an ihn übergeben wird.

+0

Es gibt Möglichkeiten, diese Post https Rendering jedes Mal wie shouldComponentUpdate Besuche zu verhindern: // www.codementor.io/reactjs/tutorial/understanding-react-js-rendering. Darüber hinaus sparen Sie Ausführungszeit, wenn Sie einen Weg finden, den Index mit dem Gerät zu behalten, anstatt ihn jedes Mal abzubilden und zu suchen. Sie ändern auch technisch das Array im Zustand, der als unveränderlich behandelt werden sollte, schlagen Sie vor, indem Sie .slice() verwenden, wie in http://stackoverflow.com/questions/26505064/react-js-what-is-the-best-way -ein-Wert-zu-einem-Array-in-state hinzufügen –

Antwort

8

Sie können die immutability helpers reagieren verwenden.

Aus der Dokumentation:

Einfache Push

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

initialArray ist nach wie vor [1, 2, 3].

So für Ihr Beispiel wollen Sie so etwas wie dies zu tun:

if (index !== -1) { 
    var deviceWithMods = {}; // do your stuff here 
    this.setState(update(this.state.devices, {index: {$set: deviceWithMods }})); 
} 

Je nachdem, wie komplex Ihr device Modell könnte man einfach ‚ändern‘, um die Objekteigenschaften in situ:

if (index !== -1) { 
    this.setState(update(this.state.devices[index], {name: {$set: 'a new device name' }})); 
} 
+0

Mein 'initialArray' ist ein Array von Instant-Objekten; Ich habe 'MyObject()' und 'initialArray.push (neues MyObject (object))' ist, wie ich sie füge. Als ich Ihren Ansatz versuchte, erhalte ich während der Initialisierung einen Fehler in diesem Objekt. Es sagt, kann nicht Eigentum von unbekannten lesen; es sucht nach einem Feld in "Objekt". Wird mit diesem 'Update' jedes Objekt neu erstellt, und deshalb schlägt es fehl? – Kousha

+0

Ich glaube, du änderst die Struktur des Staates. Überprüfen Sie 'Geräte' vor Ihrer 'var updatedDevices ...' Zeile und' updatedDevices' danach. Ich denke, die Struktur wird anders sein. – Clarkie

+0

Ich würde immer noch denselben Fehler erhalten, selbst wenn ich 'this.setState' auskommentiere. Es ist die "Hilfe" -Funktion, die diesen Fehler verursacht. – Kousha

1

Meiner Meinung nach mit reactive state, nur Dinge speichern, die wirklich mit "state", wie Dinge an, aus, aber natürlich gibt es Ausnahmen.

Wenn ich Sie wäre, würde ich die Anordnung der Geräte als Variable wegziehen und die Dinge dort gesetzt, so gibt es, was ich tun könnte:

var devices = []; 

var MyComponent = React.createClass({ 
    ... 
    updateSomething: function (device) { 

     var index = devices.map(function(d){ 
      return d.id; 
     }).indexOf(device.id); 

     if (index !== -1) { 
      // do some stuff with device 
      devices[index] = device; 

      if(NeedtoRender) { 
       this.setState({devices:devices}); 
      } 
     } 
    } 
}); 
0

Aus irgendeinem Grund funktionierten die obigen Antworten nicht für mich.viele Studien nach der unten tat

if (index !== -1) { 
      let devices = this.state.devices 
      let updatedDevice = {//some device} 
      let updatedDevices = update(devices, {[index]: {$set: updatedDevice}}) 
      this.setState({devices: updatedDevices}) 
    } 

Und ich importiert update von immutability-helper basierend auf der Kenntnis von: https://reactjs.org/docs/update.html

Verwandte Themen