动态组件怎么可能覆盖彼此的状态?
How is it possible that dynamic components overwrite each other's states?
我创建了基于 Redux 调度的房间对象创建的动态 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>
)
})
}
每个房间的细节都安装正确。我创建了一个函数来维护一个数组中的 10 个对象。然而,当数组被传递到 Rechart 时,我的组件似乎在同一状态之上更新。
class Room extends Component {
linechart = () => {
const { timestamp, temperature, humidity, name } = this.props
const { chartData } = this.state
if(chartData.length > 9) chartData.shift()
chartData.push({
name,
timestamp: moment(timestamp).format('mm:ss'),
temperature,
humidity})
}
}
如您所见,组件详细信息显示正确。然而,chartData 的值以相同的状态存储,尽管它们是唯一的组件。
I 运行 间隔为 1 秒的函数,日志显示状态正在以 0.5 秒的间隔更新。这意味着两个 <Room/>
组件都使用相同的 <LineChart/>
组件。
有谁知道如何解决这个问题?
为了更新 array
中的项目,我建议使用存储在其中的 spread syntax. Spread syntax works by shallow copying the array, which keeps a reference to the original array, but allows you to overwrite any data types。这使数组保持不变。
我不确定您从哪里获取数据,但由于您的 rooms
数量有限,因此数组的结构应该如下所示:
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
]
然后您可以简单地将其存储到 state
并在需要时 map 覆盖数组并使用传入数据更新其属性。但是,这假设传入数据包含所有 rooms
。如果您只需要更新 rooms
数组中的特定 room
,那么您可以将 id
(或唯一标识它的东西)与传入的新数据 id
进行比较.
例如,一个新的更新进来了,但它只是更新Room1
,那么我们可以这样做..
传入数据
data: [
{
name: "Room1",
humidity: 11,
tempature: 30,
timestamp: "Sat May 25 2019 22:23:06 GMT-0700",
}
];
当前数据存储在state
中为"rooms"
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
})
}));
像 pop
和 shift
一样使用 array prototypes
改变存储在 state
中的原始数组,React 不处理其 state
的改变。但是,您可以 clone
room
数组与 Array.from() 或者简单地创建一个新的数组实例并使用一些数组 prototype
函数改变这个新实例,但是您 must then re-set 这个新实例数组到 state
来覆盖旧数组——React 可以毫无问题地处理这个问题。它只是不如传播语法那么干净。
工作示例包括 spread syntax
和 Array.prototype
选项以及 setInterval
:
通过 id
和 setInterval
随机更新数组中的一项的工作示例:
我创建了基于 Redux 调度的房间对象创建的动态 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>
)
})
}
每个房间的细节都安装正确。我创建了一个函数来维护一个数组中的 10 个对象。然而,当数组被传递到 Rechart 时,我的组件似乎在同一状态之上更新。
class Room extends Component {
linechart = () => {
const { timestamp, temperature, humidity, name } = this.props
const { chartData } = this.state
if(chartData.length > 9) chartData.shift()
chartData.push({
name,
timestamp: moment(timestamp).format('mm:ss'),
temperature,
humidity})
}
}
如您所见,组件详细信息显示正确。然而,chartData 的值以相同的状态存储,尽管它们是唯一的组件。
I 运行 间隔为 1 秒的函数,日志显示状态正在以 0.5 秒的间隔更新。这意味着两个 <Room/>
组件都使用相同的 <LineChart/>
组件。
有谁知道如何解决这个问题?
为了更新 array
中的项目,我建议使用存储在其中的 spread syntax. Spread syntax works by shallow copying the array, which keeps a reference to the original array, but allows you to overwrite any data types。这使数组保持不变。
我不确定您从哪里获取数据,但由于您的 rooms
数量有限,因此数组的结构应该如下所示:
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
]
然后您可以简单地将其存储到 state
并在需要时 map 覆盖数组并使用传入数据更新其属性。但是,这假设传入数据包含所有 rooms
。如果您只需要更新 rooms
数组中的特定 room
,那么您可以将 id
(或唯一标识它的东西)与传入的新数据 id
进行比较.
例如,一个新的更新进来了,但它只是更新Room1
,那么我们可以这样做..
传入数据
data: [
{
name: "Room1",
humidity: 11,
tempature: 30,
timestamp: "Sat May 25 2019 22:23:06 GMT-0700",
}
];
当前数据存储在state
中为"rooms"
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
})
}));
像 pop
和 shift
一样使用 array prototypes
改变存储在 state
中的原始数组,React 不处理其 state
的改变。但是,您可以 clone
room
数组与 Array.from() 或者简单地创建一个新的数组实例并使用一些数组 prototype
函数改变这个新实例,但是您 must then re-set 这个新实例数组到 state
来覆盖旧数组——React 可以毫无问题地处理这个问题。它只是不如传播语法那么干净。
工作示例包括 spread syntax
和 Array.prototype
选项以及 setInterval
:
通过 id
和 setInterval
随机更新数组中的一项的工作示例: