【发布时间】:2020-05-22 19:37:41
【问题描述】:
在下面的代码中,如果 counters 已经等于状态,我不明白为什么我们需要以下行。在做什么?我可以删除该行吗?
counters[index] = { ...counters[index] };
这就是全部。
class App extends Component {
state = {
counters: [
{ id: 1, value: 0 },
{ id: 2, value: 0 },
{ id: 3, value: 0 },
{ id: 4, value: 0 }
]
};
handleIncrement = counter => {
const counters = [...this.state.counters];
const index = counters.indexOf(counter);
counters[index] = { ...counters[index] };
counters[index].value++;
this.setState({ counters });
};
【问题讨论】:
-
这样做是为了避免变异状态。第一轮解构复制了外部数组,但是为了安全地更新嵌套对象而不发生变异,它也需要被复制。
-
谢谢,我有点明白,但不完全明白。我记得在人们使用 .slice() 之前的一些教程中。那会解决同样的问题,所以我不需要那条线吗?也许如果我制作第一个 counters= [...this.state.counters.slice()],那么它就是完整的副本,与状态无关?我还是大雾。
-
问题是由于对象和数组作为引用存储在变量中。复制外部数组不会破坏对内部对象的引用。我在this answer 中写了一个很长的解释,关于为什么以及如何制作嵌套副本,如果您想通读它可能会使事情更清楚(从解释开始)。
-
阅读你的解释,想了一会儿之后,我想我已经把头绕在了它周围。所以在数组名称之前添加 ... 具有复制该数组的效果(但只是在层?),所以它第一次创建计数器的副本(所以计数器有一个唯一的引用),但它的内部仍然是指原始状态值(不是唯一的引用),因此当我设置内部值时我想不直接将其设置为 counters[index] ,因为当我们执行 counters[index].value++ 时,这最终会改变状态,因为它仍然指的是状态?我的思路清晰吗?
-
是的,听起来你已经掌握了!
标签: reactjs