Logo
Section 1 / 4

ImmutableJS 简介

学习如何通过引入不可变性来提升应用程序的性能并避免状态变更错误!

导入

ImmutableJS 简介

学习如何通过引入不可变性来提升应用程序的性能并避免状态变更错误!

正如我们在第4章:Redux中所发现的,不可变性在开发应用时非常有帮助!它让数据的变化更容易被理解和追踪,因为数据无法从其他地方被意外修改。

问题是,JavaScript 默认是一种可变的语言。其他不熟悉不可变性概念的开发者可能会不小心修改状态,从而以意想不到的方式破坏我们的应用。

为此,Facebook 发布了第二款库 Immutable.js,为 JavaScript 添加了不可变数据结构!让我们来看看它是如何工作的。

ImmutableJS 提供了一个便捷的 fromJS 函数,可以将普通的 JavaScript 对象和数组转换为不可变的数据结构。(它还提供了 toJS 方法,用于将不可变结构重新转回普通对象和数组)我们来创建一个不可变对象:

1import { fromJS } from 'immutable'; 2 3var immutableObject = fromJS({ 4 some: 'object' 5});

如果你现在尝试执行 immutableObject.some = 'notobject',也就是试图修改这个对象内部的数据,你会发现这些更改不会生效,因为这些操作并不会真正改变原对象。这就是不可变数据结构的强大之处——你可以确切地知道它的状态。

1import { fromJS } from 'immutable'; 2 3let immutableObject = fromJS({ 4 some: 'object' 5}); 6 7immutableObject.some = 'notobject'; 8 9console.log(immutableObject); // 不会改变

你可能会想:“那我们该怎么设置属性呢?” 其实,ImmutableJS 仍然提供了 set 和 setIn 方法来安全地更新属性!我们来看一个例子:

1import { fromJS } from 'immutable'; 2 3var immutableObject = fromJS({ 4 some: 'object' 5}); 6 7immutableObject.set('some', 'notobject'); 8console.log(immutableObject);

如果你运行上面的代码,仍然会得到最初的对象。为什么?

因为 immutableObject 是不可变的,当你调用 set 时,实际上返回的是一个包含新变化的新不可变对象。没有任何数据被直接修改,这类似于我们在 Redux reducer 中使用 Object.assign 的方式!

让我们验证一下效果:

1import { fromJS } from 'immutable'; 2 3var immutableObject = fromJS({ 4 some: 'object' 5}); 6 7newObject = immutableObject.set('some', 'notobject'); 8console.log(newObject);

变化已经生效,太棒了!而 immutableObject 本身仍然是原来的 { some: 'object' },没有发生任何改变。

正如我之前提到的,这其实和我们在 Redux reducer 中的做法非常相似。那么如果我们在这里使用 ImmutableJS 会怎样?让我们试试看!

状态管理

不可变 Redux