雨夜带刀's Blog

从 React 的组件更新谈 Immutable 的应用

在上一篇文章《Immutable 在 JavaScript 中的应用》 中主要介绍了 Immutable 之于 JavaScript。而基于 Immutable 的特性,将其应用在 React 项目的开发中非常合适,解决了 React 中的一些痛点,能进一步提升 React 组件的性能以及更好的管理组件的状态。

在介绍 Immutable 如何在 React 中应用之前,先来谈谈 React 组件是如何更新的。

React 是基于状态驱动的开发,可以将一个组件看成是一个有限状态机,组件要更新,必须更新状态。

通常说的组件的状态就是组件的 state 对象,state 是可以由当前组件自行修改更新的,这种自更新的状态的为了便于理解区分可以称之为“动态”的状态。但除了更新 state 外,组件还可以通过 props 来更新,props 属性不能由组件自行修改,必须由父组件来修改,然后再传递给当前组件,更新组件的 props 也能引起组件的更新,可以将 props 称之为“静态”的状态。这样的状态区分是广义上的,如果你不认可 props 也是状态也没关系,这里可以不用拘泥于文字。

Immutable 在 JavaScript 中的应用

Mutable 对象

在 JavaScript 中,对象是引用类型的数据,其优点在于频繁的修改对象时都是在原对象的基础上修改,并不需要重新创建,这样可以有效的利用内存,不会造成内存空间的浪费,对象的这种特性可以称之为 Mutable,中文的字面意思是「可变」。

对于 Mutable 的对象,其灵活多变的优点有时可能会成为其缺点,越是灵活多变的数据越是不好控制,对于一个复杂结构的对象来说,一不小心就在某个不经意间修改了数据,假如该对象又在多个作用域中用到,此时很难预见到数据是否改变以及何时改变的。

var obj = { /* 一个复杂结构的对象 */ };

doSomething(obj);
// 上面的函数之行完后,此时的 obj 还是最初的那个 obj 吗?

针对这种问题,常规的解决办法可以通过将对象进行深拷贝的形式复制出一个新的对象,再在新对象上做修改的操作,这样能确保数据的可控性,但是频繁的复制会造成内存空间的大量浪费。

var obj = { /* 一个复杂结构的对象 */ };

// copy 出一个新的 obj2
// 但是 copy 操作会浪费内存空间
var obj2 = deepClone(obj);

doSomething(obj2);
// 上面的函数之行完后,无论 obj2 是否变化,obj 肯定还是原来那个 obj
头像

雨夜带刀

前端开发工程师,技术宅,现居北京。

雨夜带刀的开源项目

easy.js
一个简洁的 JavaScript 类库,集成了模块加载器,同时也有包含了常见的的组件库,可访问项目网站
seed
符合 AMD 规范的 JavaScript 模块加载器。
ecope
从 easy.js 组件库中移值过来的基于 jQuery 的组件库,简单实用,API 风格统一。