Javascript 动态组件如何可能相互覆盖';美国?
我已经创建了动态房间组件,这些组件是基于Redux调度的房间对象创建的Javascript 动态组件如何可能相互覆盖';美国?,javascript,reactjs,react-state-management,Javascript,Reactjs,React State Management,我已经创建了动态房间组件,这些组件是基于Redux调度的房间对象创建的 { rooms && rooms.map((room, index) => { const { name, temperature, humidity, timestamp } = room return ( <Col key={index} xs={12} md={6}> <Room
{
rooms && rooms.map((room, index) => {
const { name, temperature, humidity, timestamp } = room
return (
<Col key={index} xs={12} md={6}>
<Room
index={index}
name={name}
temperature={temperature}
humidity={humidity}
/>
</Col>
)
})
}
如您所见,组件详细信息显示正确。但是,chartData的值存储在相同的状态,尽管它们是唯一的组件
我以1秒的间隔运行函数,日志显示状态以0.5秒的间隔更新。这意味着两个
组件使用相同的
组件。
有人知道如何克服这个问题吗?为了更新
数组中的项目,我建议使用。Spread语法通过浅复制数组来工作,该数组保留对原始数组的引用,但允许覆盖其中存储的任何内容。这使数组保持不变
我不确定您从何处获取数据,但由于您有有限的房间
,因此阵列的结构应如下所示:
data: [
{
name: "Room1",
humidity: 11,
tempature: 30,
timestamp: "Sat May 25 2019 22:23:06 GMT-0700",
},
{
name: "Room2",
humidity: 11,
tempature: 25,
timestamp: "Sat May 25 2019 22:23:06 GMT-0700",
},
...etc
]
然后,您可以简单地将其存储到状态
,并在需要时通过阵列更新其属性,并使用传入数据更新其属性。但是,这假设传入的数据包含所有房间
。如果只需要更新房间
数组中的特定房间
,则可以将id
(或唯一标识它的内容)与传入的新数据id
进行比较
例如,一个新的更新进来了,但它只是更新Room1
,然后我们可以这样做
传入数据
data: [
{
name: "Room1",
humidity: 11,
tempature: 30,
timestamp: "Sat May 25 2019 22:23:06 GMT-0700",
}
];
当前数据存储在状态
为“房间”
使用数组原型
如pop
和shift
对存储在state
中的原始数组进行变异,React不会处理对其状态的变异。但是,您可以使用
克隆
房间数组,或者简单地创建一个新的数组实例,并使用一些数组原型函数对这个新实例进行变异,但是您必须然后将这个新实例数组重新设置为状态以覆盖旧数组——React会毫无问题地处理这个问题。它只是没有spread语法那么清晰
工作示例包括
扩展语法
和数组。原型
带有设置间隔的选项
:
通过id
使用setInterval
随机更新数组中一个项目的工作示例:
您的图表数据似乎是由组件状态提供的,而不是由道具提供的。
const{chartData}=this.state
应该是const{chartData}=Object.assign({},this.state)
我认为问题不在于状态的使用。我使用了1秒的间隔,日志显示状态以0.5秒的间隔更新。这意味着两个组件使用的是同一个组件。我认为您不应该像处理chartData.shift()
那样改变状态。组件室有状态吗?如果是,为什么不使用setState存储图表数据而更改图表数据?如果没有setState,将不会调用render()来刷新绘图。感谢您指出这一点。问题似乎在于我是如何变异状态的,我直接移位()和弹出()状态。我解决这个问题的方法是将原始状态扩展到另一个变量中并对其进行变异,然后以与您演示的方式类似的方式设置状态。
data: [
{
name: "Room1",
humidity: 11,
tempature: 30,
timestamp: "Sat May 25 2019 22:23:06 GMT-0700",
}
];
this.setState(prevState => ({
...prevState, // spread out any previous state not related to "rooms"
rooms: prevState.rooms.map(room => { // map over "rooms" and pull out each "room" object
return room.name === data[0].name // if the "room.name" matches incoming data's "name", then...
? { ...data[0] } // spread and overwrite it with incoming data
: room; // else leave the "room" as is
})
}));