ReactJS更新状态数组中的单个对象

Kou*_*sha 13 javascript reactjs

我有一个叫做对象this.state.devices数组的状态device.

说我有一个功能

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});
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是,每次this.updateSomething调用时,整个数组都会更新,因此整个DOM都会被重新渲染.在我的情况下,这导致浏览器冻结,因为我每隔一秒调用此函数,并且有许多device对象.但是,在每次通话时,实际上只更新了这些设备中的一个或两个.

我有什么选择?

编辑

在我的确切情况下,a device是一个定义如下的对象:

function Device(device) {
    this.id = device.id;
    // And other properties included
}
Run Code Online (Sandbox Code Playgroud)

所以数组中的每个项目state.devices都是这个特定的瞬间Device,即我所拥有的某个地方:

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

我的最新答案如何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);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题现在是我得到一个错误,说不能读取未定义的值id,它来自function Device(); 似乎新new Device()的被调用而且device没有传递给它.

Cla*_*kie 8

您可以使用反应不变性助手.

来自文档:

简单的推动

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

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

因此,对于您的示例,您将要执行以下操作:

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

根据您的device模型的复杂程度,您可以在原位"修改"对象属性:

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