我正在使用Map类。
我有这样的状态:
{
rows: new Map([])
}
每一行代表一个表中的一个条目。 我想以线程安全的方式独立和异步地更新每一行。
在每次修改都是这样的情况下(假设“ fooId”已经插入到Map中),执行setState的惯用React方法是什么:
const rows = this.state.rows;
const row = rows.get("fooId");
row.status = '75%';
this.setState({
rows: rows
});
答案 0 :(得分:1)
惯用的方法是使用功能setState()
,因为您要更新现有值而不是批量替换。
this.setState((prevState) => {
const nextRows = new Map(prevState.rows)
// Creating a new Map this way does not clone the original data
// This means that any update to an object in the map will update the previous map.
// To avoid this, we create a new object using object spread and assign the updated value there.
// This has the benefit of reducing memory allocations as well, if performance is your concern.
// Though it should not be until you have proven it to be a concern.
const nextEntry = {
...nextRows.get('fooId'),
status: '75%'
}
return { rows: nextRows.set('fooId', nextEntry) }
})
使用ImmutableJS可以使此操作变得容易一些
this.setState(prevState => ({
rows: prevState.rows.update('fooId', entry => ({ ...entry, status: '75%' }))
}))
此外,只需要与@Jonas所说的矛盾即可:克隆地图时,它仅会克隆键和地图值之间的映射。它不会克隆地图的值。这意味着所需的内存消耗比您想象的要低得多。
如果您确定不会使用旧地图或旧地图中引用的任何对象,则甚至可以取消使用object-spread和您只会承担复制键/值映射(和创建新对象)的影响。如果您错了(可能很容易出错),这可能会导致一些真正令人困惑的错误,因此我会坚持使用不变的东西。
如果此确实成为性能问题,则可以以其他方式构造数据,以使变更分配更少。