2015-08-27 56 views
12

我有一個名爲this.state.devices的狀態,它是一個device對象的數組。ReactJS更新狀態數組中的單個對象

說我有一個函數在這裏

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}); 
    } 
} 

問題是,每次this.updateSomething被調用時,整個數組被更新,所以整個DOM被重新呈現。在我的情況下,這會導致瀏覽器凍結,因爲我每秒都會調用此函數,並且有很多對象。但是,在每次通話中,實際只更新一個或兩個這些設備。

我有什麼選擇?

EDIT

以我確切的情況,一個device是定義如下的物體:

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

所以的state.devices陣列中的每個條款是本Device的特定的瞬間,即某處我會有:

addDevice: function (device) { 
    var newDevice = new Device(device); 
    this.setState({devices: this.state.devices.push(device)}); 
} 

我更新ED怎麼回答到updateSomething,我有:

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); 
    } 
} 

現在的問題是,我得到,說無法讀取的id的未定義值的誤差,它是從未來function Device();似乎正在調用新的new Device(),並且device未傳遞給它。

+0

有辦法避免每次如shouldComponentUpdate渲染,看看這個帖子https://開頭www.codementor.io/reactjs/tutorial/understanding-react-js-rendering。此外,如果您找到一種方法將索引與設備保持在一起,而不是每次映射和搜索,都會節省一些執行時間。你也在技術上改變狀態數組,應該被視爲不可變的,建議使用.slice()按照http://stackoverflow.com/questions/26505064/react-js-what-is-the-best-way添加數值到數組狀態 –

回答

8

可以使用反應immutability helpers

從文檔:

簡單推

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

initialArray仍然是[1,2,3]。

因此,對於你的榜樣,你會想要做這樣的事情:

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

根據您的device模型是多麼複雜,你可能只是「修改」就地對象屬性:

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

我的'initialArray'是一個對象的瞬間數組;即我有'MyObject()'和'initialArray.push(new MyObject(object))'是我如何添加它們。當我嘗試你的方法時,我在初始化過程中遇到了這個對象內部的錯誤。它說不能讀取未知的財產;它正在'對象'中尋找一個字段。這是「更新」重新創建每個對象,這就是爲什麼它失敗? – Kousha

+0

我認爲你正在改變國家的結構。在'var updatedDevices ...'行和'updatedDevices'之前檢查'devices'。我認爲結構會有所不同。 – Clarkie

+0

即使我註釋掉'this.setState',我仍然會得到同樣的錯誤。它是引發這個錯誤的'help'函數。 – Kousha

1

在我看來,與反應狀態一樣,只存儲與「狀態」相關的事物,例如事物開啓,關閉,但當然也有例外。

如果我是你,我會拉遠設備作爲變量的陣列和設置的東西在那裏,所以我可以做什麼:

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

由於某種原因,以上答案不適用於我。多次試驗之後,下面做:

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

我基於從紙幣進口從immutability-helperupdatehttps://reactjs.org/docs/update.html

相關問題