[英]ReactJS updating a single object inside a state array
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.这里的问题是每次调用
this.updateSomething
时,整个数组都会更新,因此整个 DOM 都会重新渲染。 In my situation, this causes the browser to freeze as I am calling this function pretty every second, and there are many device
objects.在我的情况下,这会导致浏览器冻结,因为我几乎每秒都在调用此函数,并且有很多
device
对象。 However, on every call, only one or two of these devices are actually updated.然而,在每次调用中,这些设备中实际上只有一两个被更新。
What are my options?我有哪些选择?
EDIT编辑
In my exact situation, a device
is an object that is defined as follows:在我的确切情况下,
device
是一个定义如下的对象:
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
, ie somewhere I'd have:所以
state.devices
数组中的每个项目都是这个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()
;现在的问题是我得到一个错误,说无法读取
id
的未定义值,它来自function Device()
; it seems that a new new Device()
is being called and the device
is not passed to it.似乎正在调用一个新的
new Device()
并且没有将device
传递给它。
You can use the 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' }}));
}
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});
}
}
}
});
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我根据以下注释从
immutability-helper
导入了update
: https ://reactjs.org/docs/update.html
I solve it doing a array splice in object I wish modify, before update component state and push of object modified again.我解决了它在我希望修改的对象中进行数组拼接,然后更新组件状态并再次推送修改的对象。
Like example below:像下面的例子:
let urls = this.state.urls;
var index = null;
for (let i=0; i < urls.length; i++){
if (objectUrl._id == urls[i]._id){
index = i;
}
}
if (index !== null){
urls.splice(index, 1);
}
urls.push(objectUrl);
this.setState((state) => {
return {urls: urls}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.