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
ReactJS updating a single object inside a state array
提问by Kousha
I have a state called this.state.devices
which is an array of device
objects.
我有一个称为对象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.updateSomething
is 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 device
objects. 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 device
is 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.devices
is 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 device
is 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 device
model 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 update
from immutability-helper
based 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});
}
}
}
});