为什么不可变性很重要
在之前的示例代码中,我们建议使用.slice()
运算符来拷贝一份squares
数组,再在其副本上进行数据改动,以防止原有的数组被修改。现在,我们来具体谈谈它的内涵,和这么做的重要性。
通常来说,修改数据的方法有两种。第一种方法是通过直接改动变量的值来修改(mutate)原有数据,第二种方法是使用一份改动后的副本,以此替换(replace)原有数据。
改动(mutate)原数据
code
var player = {score: 1, name: 'Jeff'}; player.score = 2; // 现在 player 是 {score: 2, name: 'Jeff'}
不改动(mutate)原数据
code
var player = {score: 1, name: 'Jeff'};
var newPlayer = Object.assign({}, player, {score: 2});
// 现在 player 没有改变, 而 newPlayer 是 {score: 2, name: 'Jeff'}
// 或者使用对象展开符:
// var newPlayer = {...player, score: 2};
最终的结果是一样的。但是,不直接改动基础数据的方法却能带来一些额外的好处:它有助于提升组件或者整个应用的性能。
更简单的 撤销/重做 和 穿越功能
不可改变性 也能让一些复杂的特性实现起来更容易。例如,在本教程后期,我们将要实现在棋局的不同阶段间穿越的功能。避免数据的变动(mutation),能让我们保持对旧版本数据的引用。如果我们需要的话,就能在它们之间切换。
追踪变动
对于被直接改动(mutate)的对象,我们难以判断它们是否被修改,因为所以改动都直接在原对象上进行的。这要求比较当前对象和之前的拷贝的副本,遍历整个对象数,比较每个变量与值。这个过程可能会变得越来越复杂。
而判断不可变对象是否被改动则是相当容易的。 如果被引用的对象与之前的不同,则对象已更改。就这么简单。
在React中 确定何时重新渲染
在React中,当建立纯组件时,不可改变性带来的好处最明显。对于不可改变的数据,我们能很容易地确认改动是否发生,借此,我们就可以确定组件何时要求被重新渲染。
想要了解shouldComponentUpdate()
以及如何构建纯组件,请查看优化性能。