ReactJS在状态数组中更新单个对象
ReactJS updating a single object inside a state array
我有一个名为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});
}
}
这里的问题是,每次this.updateSomething
被调用,整个数组被更新,所以整个DOM得到重新渲染。在我的情况下,这会导致浏览器冻结,因为我几乎每秒都在调用这个函数,并且有许多device
对象。然而,在每次调用中,实际上只有一两个设备更新了。
我有什么选择?
编辑
在我的确切情况下,device
是一个对象,定义如下:
function Device(device) {
this.id = device.id;
// And other properties included
}
所以state.devices
数组中的每一项都是这个Device
的一个特定瞬间,也就是说,在某个地方我有:
addDevice: function (device) {
var newDevice = new Device(device);
this.setState({devices: this.state.devices.push(device)});
}
我对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);
}
}
现在的问题是,我得到一个错误,说不能读取id
的未定义值,它来自function Device()
;似乎正在调用新的new Device()
,而device
没有传递给它。
你可以使用react的不变性帮助。
From the docs:
简单推
var initialArray = [1, 2, 3];
var newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]
initialArray仍然是[1,2,3].
对于你的例子,你会想这样做:
if (index !== -1) {
var deviceWithMods = {}; // do your stuff here
this.setState(update(this.state.devices, {index: {$set: deviceWithMods }}));
}
根据你的device
模型的复杂程度,你可以在原地"修改"对象属性:
if (index !== -1) {
this.setState(update(this.state.devices[index], {name: {$set: 'a new device name' }}));
}
在我看来,react state只存储与"state"真正相关的东西,比如东西打开,关闭,当然也有例外。
如果我是你,我会把设备数组作为一个变量,并在那里设置东西,所以我可能会这样做:
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});
}
}
}
});
由于某些原因,以上答案对我不起作用。经过多次试验,下面的代码成功了:
if (index !== -1) {
let devices = this.state.devices
let updatedDevice = {//some device}
let updatedDevices = update(devices, {[index]: {$set: updatedDevice}})
this.setState({devices: updatedDevices})
}
根据https://reactjs.org/docs/update.html
immutability-helper
导入update
我解决它做一个数组拼接的对象,我希望修改,之前更新组件状态和再次修改的对象推送。
就像下面的例子:
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}
});
- 使用 php/jquery 动态更新单个模态
- 如何在jQuery中的单个保存按钮上更新数据和添加数据
- 如何在AngularJS中使用单个按钮更新列
- 如何使用jQuery跟踪单个dom元素上的点击事件,并相应地更新其点击计数器
- X-editable:如何获取每行的id,以便更新单个成员
- 使用express和node.js更新mongodb中的单个记录
- 猫鼬 - 如何使用多个更新语句进行单个更新
- Javascript 更新关联数组中的单个值
- 如何在 Meteor 中使用多个输入字段和单个更新按钮更新文档
- 在指令中使用$watch的单个值对范围进行角度更新
- ExtJS 5:当更改单个存储时,所有存储都会更新
- 多个数据表表单更新与单个更新
- 用陨石更新单个包
- 正在更新mongoldb集合中的单个字段
- 如何在单个查询中更新多行数据
- 如何在d3中更新单个数据点而不触及其他元素
- 如何在Sencha touch 2中使用Ajax数据更新单个视图容器项html
- ReactJS在状态数组中更新单个对象
- 如何在AngularJS中更新单个API请求来传递不同的Query参数?
- AngularJS从一个巨大的列表中更新单个元素