【发布时间】:2019-03-16 10:43:50
【问题描述】:
我有一个名为 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认为状态从未改变!!!。这是正确的理由。我不想使用数组。 如果我使用数组作为计数器,代码绝对可以正常工作。
我在这里错过了什么?
【问题讨论】:
-
为什么不想使用数组?这似乎更适合这个用例。
-
如果你使用
setState改变状态,react就会知道它已经改变了。 -
因为我这是一个实验。在实际场景中,我想为服务器加载大量数据[当然是延迟加载]。每个数据都将具有来自 Db 的唯一 UUID,我想创建每个 UUID 和数据本身的映射。所以我将为每个数据创建组件并根据每个组件的 id == UUID 处理交互..
-
@Amir : 谢谢你的回复,我认为 react 的状态是 map 对象的内存位置或每个键的内存....现在每个键又是一个对象...所以...没有更改内存位置..我的意思是这是我的理解...但我再次不确定...您是否能够在您的经验中使用地图?
-
你不应该改变状态或者它的任何字段。您对
setState的使用是错误的。您应该以setState(previousState => {/*...*/})的形式使用它,并且您应该创建一个全新的counterMap并替换它,不要更新它。因为状态是不可变的