【译】Immutable.js很吓人?我来告诉你如何开始

原文 - Immutable.js is intimidating. Here’s how to get started.

你从许多渠道中了解到,你应该使用Immutable。你也想去使用,但是不确定为什么去使用。而当你去看官方 文档 时,映入你眼帘的第一个代码片段是:

identity<T>(value: T): T

你会想:呃...还是算了吧。

这是一篇简单、快速帮你入门Immutable的文章,绝对不会让你失望。

一年前,在Pilcro,我向开发团队推荐了Immutable。迄今为止,这被证明是最明智的决定。我们的应用现在具有更强的可读性、更好的健壮性、更少的错误以及可预测性。

基础

标准js数据格式转换成Immutable

js中,我们知道两种常见的数据类型:Object{}Array[]Immutable的思路:

  • Object{} 变为 MapMap({})
  • Array[] 变为 ListList([])

更具体点,是使用Immutable提供的MapListfromJS函数:

import { Map, List, fromJS } from 'immutable';
// 原生 js 数据类型
const person = {
  name: 'Will',
  pets: ['cat', 'dog']
};
// 等同于 Immutable 中的:
const immutablePerson = Map({
  name: 'Will',
  pets: List(['cat', 'dog'])
});
// 或者 ...
const immutablePerson = fromJS(person);

formJS是个非常有用的函数,它会把嵌套的数据结构转换成Immutable对象。它在转换的过程中会根据数据自行创建MapsLists

Immutable转换为标准js数据格式

要想从Immutable对象中取回你的标准js数据格式,你只需要调用Immutable对象的toJS函数即可:

import { Map } from 'immutable';
const immutablePerson = Map({ name: 'Will' });
const person = immutablePerson.toJS();
console.log(person); // 打印 { name: 'Will' };

数据结构应该被认为是原生js数据结构,或者Immutable对象

开始使用Immutable

在解释为什么Immutable很有用之前,先给出三个代码片段告诉你Immutable如何去帮助你。

从嵌套的数据结构中获取不存在的数据值

首先,原生js

const data = { my: { nested: { name: 'Will' } } };
const goodName = data.my.nested.name;
console.log(goodName); // 打印 Will
const badName = data.my.lovely.name;
// throws error: 'Cannot read name of undefined'
// 'lovely' 属性不存在,所以报错

再来看看Immutable:

const data = fromJS({ my: { nested: { name: 'Will' } } });
const goodName = data.getIn(['my', 'nested', 'name']);
console.log(goodName); // 打印 Will
const badName = data.getIn(['my', 'lovely', 'name']);
console.log(badName); // 打印 undefined - 不会抛出异常

上面的例子中,原生js代码会抛出异常,但是Immutable并不会。

这是因为我们使用getIn()函数去获取嵌套的数据值。数据值的key路径不存在(换句话说,对象并非是你期望的嵌套结构),它仅仅返回undefined并不会抛出异常。

你不必像下面这样嵌套的去判断数据值是否存在:

if (data && data.my && data.my.nested && data.my.nested.name) { ...

这个简单的特性,让你的代码可读性更好,代码简洁并且健壮性更好。

链式操作

首先,原生js

const pets = ['cat', 'dog'];
pets.push('goldfish');
pets.push('tortoise');
console.log(pets); // 打印 ['cat', 'dog', 'goldfish', 'tortoise'];

再来看看Immutable:

const pets = List(['cat', 'dog']);
const finalPets = pets.push('goldfish').push('tortoise');
console.log(pets.toJS()); // 打印 ['cat', 'dog'];
console.log(finalPets.toJS()); // 打印 ['cat', 'dog', 'goldfish', 'tortoise'];

因为List.push返回操作之后的结果,我们可以在后面继续链式操作,而原生数组的push函数返回操作之后新数组的长度。

这是一个非常简单的链式操作例子,但是它说明了Immutable的强大功能。

这可以让你以函数式和简洁的方式去处理各种数据操作。

Immutable对象的操作总是返回操作之后的结果

不可变数据

它被称为不可变,所以我们需要讨论一下为什么这很重要。

比如你使用Immutable创建一个对象并更新了它,但是它初始数据结构仍然保持不变。这就是不可变

const data = fromJS({ name: 'Will' });
const newNameData = data.set('name', 'Susie');
console.log(data.get('name')); // 打印 'Will'
console.log(newNameData.get('name')); // 打印 'Susie'

在这个例子中,我们可以看到初始的data对象并没有改变。这就意味着当你更新它的name属性值为Susie时,并不会伴随着不可预知的行为。

这个简单的特性是非常强大的,特别是当你去搭建一些复杂的应用。这是Immutable的核心。

Immutable对象上的操作并不会改变原对象,而是创建一个新对象

为什么Immutable很有用

脸书的一些工程师在文档首页整理了一些使用Immutable的益处,但是有点绕。以下是我整理的一些为什么你应该开始使用Immutable

你的数据结构是可预测的

因为你的数据结构是Immutable,你对自己的数据结构如何操作一清二楚。在复杂web应用中,这意味当你针对UI 的数据结构进行很微小的改动时,不会发生额外的、令人啼笑皆非的重新渲染问题。

数据操作的健壮性

通过使用Immutable去操作数据,你的这些操作很难会出现错误。Immutable为你做了许多脏活、累活:捕获异常提供默认值开箱即用的创建嵌套数据结构

简洁并且可读性的代码

一开始你可能对Immutable的函数式设计很困惑,但一旦你掌握了,链式函数调用会让你的代码更少、可读性更好。这对团队保持代码的一致性很有帮助。

后续学习

不可否认,Immutable的学习曲线不是很平滑,但是非常值得。Get started的学习只是个开胃菜。

以下是之前提到的一些注意事项。如果你铭记于心,使用Immutable就如在水中的鸭子般轻松。

  • 数据结构应该被认为是原生js数据结构,或者Immutable对象
  • Immutable对象的操作总是返回操作之后的结果
  • Immutable对象上的操作并不会改变原对象,而是创建一个新对象

祝你好运!

如果你喜欢这篇文章,请去原文点个赞并分享给其他人,也欢迎访问我们公司网站Pilcro.comPilcro是一个品牌设计软件。

关注下面的标签,发现更多相似文章
评论
说说你的看法