我有一个位于this.state.points的点数组。我有一个updatePoint()函数,用于更新此数组中的各个点。我认为使用.slice()会让我的状态保持不变,直到我调用setState,但是当我设置了points [i]的值后,我调试了this.state.points,我看到它已经更新了。在调用setState之前,如何防止状态更新?
updatePoint(i, point) {
console.log('updatePoint '+i)
let points = this.state.points.slice()
points[i] = point
this.setState({points: points})
}
此版本也不起作用:
updatePoint(i, point) {
console.log('updatePoint '+i)
let points = this.state.points.slice()
points.forEach((j) => {
points[j] = Object.assign({}, this.state.points[j])
})
points[i] = point
this.setState({points: points})
}
答案 0 :(得分:0)
Array.slice
不执行深层复制,因此如果您的this.state.points
是一个对象数组,则还需要复制这些对象项。
您可以使用Object.assign
复制对象。
答案 1 :(得分:0)
您可以使用ES6附带的扩展运算符(...):
updatePoint(i, point) {
console.log('updatePoint '+i)
let points = [...this.state.points]
console.log("points", points);
points[i] = point;
console.log("state",this.state.points);
this.setState({points: points})
console.log(this.state.points);
}
您可以在此处进行测试(并尝试检查您自己环境中的console.log):
class Hello extends React.Component {
constructor(props){
super(props);
this.updatePoint = this.updatePoint.bind(this);
this.state = {
points: [{name: "uno"},
{name: "dos"},
{name: "tres"}]
};
console.log(this.state.points);
}
// i = 1, name: ocho
updatePoint = (i, point) => {
console.log('updatePoint '+ i)
console.log("spread", [...this.state.points]);
const newPoints = [...this.state.points];
console.log("points", newPoints);
newPoints[i] = point;
console.log("state",this.state.points);
this.setState({
points: newPoints
});
}
render() {
const nowState = this.state.points.map(item => <p key={item.name}>{item.name}</p>);
return (
<div>Hello
<button
onClick={() => this.updatePoint(1, {name: "ocho"})}
>Click
</button>
<p>Current state
{nowState}</p>
</div>);
}
}
ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
有关点差运算符的更多信息: 来自https://docs.microsoft.com/en-us/scripting/javascript/reference/spread-operator-decrement-dot-dot-dot-javascript:
允许从可迭代表达式(例如另一个数组文字)初始化数组文字的某些部分,或允许将表达式扩展为多个参数(在函数调用中)。
https://redux.js.org/docs/recipes/UsingObjectSpreadOperator.html
另一种方法是使用为下一版JavaScript提出的对象扩展语法,它允许您使用spread(...)运算符以更简洁的方式将可枚举属性从一个对象复制到另一个对象。