2015-08-27 20 views
12

Tôi có một trạng thái được gọi là this.state.devices là một mảng của các đối tượng device.ReactJS cập nhật một đối tượng duy nhất trong một dải trạng thái

Nói rằng tôi có một hàm

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

Vấn đề ở đây là mỗi lần this.updateSomething được gọi là, toàn bộ mảng được cập nhật, và do đó toàn bộ DOM được tái-rendered. Trong tình huống của tôi, điều này làm cho trình duyệt bị đóng băng khi tôi gọi hàm này khá tốt mỗi giây và có rất nhiều đối tượng device. Tuy nhiên, trên mọi cuộc gọi, chỉ một hoặc hai thiết bị này thực sự được cập nhật.

Tùy chọn của tôi là gì?

EDIT

Trong tình huống chính xác của tôi, một device là một đối tượng được định nghĩa như sau:

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

Vì vậy, mỗi mục trong mảng của state.devices là một khoảnh khắc đặc biệt của Device này, tức là một nơi nào đó tôi có:

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

Trình cập nhật của tôi ed trả lời như thế nào vào updateSomething, tôi có:

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

Vấn đề bây giờ là tôi nhận được một lỗi nói rằng không thể đọc được giá trị không xác định của id, và nó đến từ các function Device(); có vẻ như new Device() mới đang được gọi và device không được chuyển cho nó.

+0

Có nhiều cách để ngăn chặn render mỗi lần như shouldComponentUpdate, hãy kiểm tra bài này https: // www.codementor.io/reactjs/tutorial/understanding-react-js-rendering. Ngoài ra, bạn sẽ tiết kiệm thời gian thực hiện nếu bạn tìm cách giữ chỉ mục bằng thiết bị thay vì ánh xạ và tìm kiếm nó mỗi lần. Bạn cũng thay đổi về mặt kỹ thuật mảng trong trạng thái, cần được coi là không thay đổi, đề xuất sử dụng .slice() theo http://stackoverflow.com/questions/26505064/react-js-what-is-the-best-way -to-add-a-value-to-an-array-in-state –

Trả lời

8

Bạn có thể sử dụng các phản ứng immutability helpers.

Từ các tài liệu:

đơn giản đẩy

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

initialArray vẫn là [1, 2, 3].

Vì vậy, ví dụ của bạn, bạn sẽ muốn làm một cái gì đó như thế này:

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

Tùy thuộc vào độ phức tạp mô hình device của bạn là bạn có thể chỉ cần 'sửa đổi' các thuộc tính đối tượng tại chỗ:

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

'initialArray' của tôi là một mảng tức thời của một đối tượng; tức là tôi có 'MyObject()' và 'initialArray.push (new MyObject (object))' là cách tôi thêm chúng. Khi tôi thử cách tiếp cận của bạn, tôi nhận được một lỗi bên trong đối tượng này trong quá trình khởi tạo. Nó nói không thể đọc được tài sản chưa biết; nó đang tìm kiếm một trường trong 'đối tượng'. Bản cập nhật này có đang tái tạo mọi đối tượng hay không và đó là lý do tại sao nó không thành công? – Kousha

+0

Tôi nghĩ bạn đang thay đổi cấu trúc của tiểu bang. Kiểm tra 'các thiết bị' trước dòng' var updatedDevices ... 'và' updatedDevices' sau. Tôi nghĩ cấu trúc sẽ khác. – Clarkie

+0

Tôi vẫn nhận được cùng một lỗi ngay cả khi tôi nhận xét 'this.setState'. Đó là chức năng 'help' đang ném lỗi này. – Kousha

1

Theo quan điểm của tôi với trạng thái phản ứng, chỉ lưu trữ những thứ thực sự liên quan đến "trạng thái", chẳng hạn như mọi thứ bật, tắt, nhưng tất nhiên có những ngoại lệ.

Nếu tôi là bạn tôi sẽ kéo đi những mảng của các thiết bị như là một biến và thiết lập những điều đó, vì vậy có là những gì tôi có thể làm:

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

Vì lý do nào đó, các câu trả lời trên không hiệu quả đối với tôi.Sau nhiều thử nghiệm dưới đây đã làm:

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

Và tôi nhập khẩu update từ immutability-helper dựa trên phiếu từ: https://reactjs.org/docs/update.html

Các vấn đề liên quan