如果ReactJS状态具有map属性,则更改映射值不会反映状态
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果ReactJS状态具有map属性,则更改映射值不会反映状态相关的知识,希望对你有一定的参考价值。
我有一个名为Counters的组件
export default class Counters extends Component
state =
counterMap:
;
noOfComponents = 5;
componentWillMount()
var counterMap = new Map();
for (var i = 0; i < this.noOfComponents; i++)
var counter =
id: i + 1,
value: i + 1,
key: i + 1
;
counterMap.set(i + 1, counter);
this.setState( counterMap );
handleDecrease = counterId =>
// This is always Called from the inner child... Verified !
const counterMap = this.state;
const counter = counterMap.get(counterId);
counter.value = counter.value - 1;
counterMap.delete(counterId);
counterMap.set(counterId, counter);
this.setState( counterMap: counterMap );
;
render()
const counterComps = [];
this.state.counterMap.forEach(element =>
const counter = (
<Counter
data=element
onDecrease=this.handleDecrease
onIncrease=this.handleIncrease
/>
);
counterComps.push(counter);
);
return <div>counterComps</div>;
我的问题是
handleDecrease = counterId =>
// This is always Called
const counterMap = this.state;
const counter = counterMap.get(counterId);
counter.value = counter.value - 1;
counterMap.delete(counterId);
counterMap.set(counterId, counter);
this.setState( counterMap: counterMap );
这在UI中不起作用。
计数器值的更改不会反映在UI中。我的想法是因为地图本身从未改变过,只有价值发生变化......所以React认为国家从未改变过!这是正确的理由。我不想使用数组。如果我使用数组作为计数器,代码工作正常。
我在这里错过了什么?
答案
您应该始终不可更新地更新州或其任何字段:
handleDecrease = counterId =>
// This is always Called
this.setState(prevState =>
const oldCounterMap = prevState;
newCounterMap = new Map(oldCounterMap);
const counter = oldCounterMap.get(counterId);
newCounterMap.set(counterId, ...counter, value: counter.value - 1);
return Object.assign(, prevState, counterMap: newCounterMap )
);
说明:
首先,如果你需要根据旧值计算状态的新值,那么你应该使用setState
:setState(previousState => )
的这个签名,它将当前状态作为参数传递给你。
然后为了不变地更新计数器,我们首先需要克隆counterMap:
newCounterMap = new Map(oldCounterMap);
你可以看到这是一个克隆,因为newCounterMap === oldCounterMap
是false
。
然后我们继续并按照我们的喜好更新此地图:
newCounterMap.set(counterId, ...counter, value: counter.value - 1);
注意对象传播,这再次导致基于counter
创建一个全新的对象(这只是一个很好的实践,即使它不是非常必要的)。
最后,我们返回一个全新的对象来取代我们当前的状态。
return Object.assign(, prevState, counterMap: newCounterMap )
再次注意,我在这里使用了对象传播,因此我们都返回一个新对象并保持其他值不变(不覆盖state
的其他条目)
以上是关于如果ReactJS状态具有map属性,则更改映射值不会反映状态的主要内容,如果未能解决你的问题,请参考以下文章
Mapstruct 映射:如果所有源参数属性为空,则返回空对象