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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32238679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:01:10  来源:igfitidea点击:

ReactJS updating a single object inside a state array

javascriptreactjs

提问by Kousha

I have a state called this.state.deviceswhich is an array of deviceobjects.

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

Say I have a function

说我有一个功能

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 here is that every time this.updateSomethingis called, the entire array is updated, and so the entire DOM gets re-rendered. In my situation, this causes the browser to freeze as I am calling this function pretty every second, and there are many deviceobjects. However, on every call, only one or two of these devices are actually updated.

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

What are my options?

我有哪些选择?

EDIT

编辑

In my exact situation, a deviceis an object that is defined as follows:

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

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

So each item in the array of state.devicesis a specific instant of this Device, i.e. somewhere I'd have:

所以数组中的每一项state.devices都是 this 的一个特定时刻Device,即我有的地方:

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

My updated answer how on to updateSomething, I have:

我更新的答案如何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);
    }
}

Problem now is that I get an error that says cannot read the undefined value of id, and it is coming from the function Device(); it seems that a new new Device()is being called and the deviceis not passed to it.

现在的问题是我收到一个错误,提示无法读取 的未定义值id,它来自function Device(); 似乎new Device()正在调用一个 new并且device没有传递给它。

采纳答案by Clarkie

You can use the react immutability helpers.

您可以使用 react immutability helpers

From the docs:

从文档:

Simple push

简单推送

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

initialArray is still [1, 2, 3].

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

So for your example you will want to do something like this:

所以对于你的例子,你会想要做这样的事情:

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

Depending on how complex your devicemodel is you could just 'modify' the object properties in situ:

根据device模型的复杂程度,您可以就地“修改”对象属性:

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

回答by Wasim Abuzaher

For some reason above answers didn't work for me. After many trials the below did:

由于某种原因,上述答案对我不起作用。经过多次试验,下面做了:

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

And I imported updatefrom immutability-helperbased on the note from: https://reactjs.org/docs/update.html

我进口update来自immutability-helper:基于音符从https://reactjs.org/docs/update.html

回答by Jim

In my opinion with react state, only store things that's really related to "state", such as things turn on, off, but of course there are exceptions.

在我看来,react state 只存储真正与“状态”相关的东西,比如东西打开、关闭,当然也有例外。

If I were you I would pull away the array of devices as a variable and set things there, so there is what I might do:

如果我是你,我会将设备数组作为变量拉出并在那里设置,所以我可能会这样做:

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