⚡ 30 秒速记
- 更新生成新结果,旧值继续可用
- 结构共享复用未变分支,避免整树复制
- 引用比较帮助发现变化,也支持历史快照
- 不可变理念不等于必须使用专门库
- 原生对象互转与深层更新也有成本
不可变数据像保留每一版草稿,修改时生成新版本,旧版本不被偷偷改写。 为了避免复制整棵树,只重建变化路径,其他分支继续共享。这样浅比较能利用引用识别变化,撤销和回放也有可靠基础。普通对象配合规范更新也能做到,专门库提供更系统的数据结构,但要考虑调用习惯、互转成本和团队维护能力。
版本校准: 原理文章中的代码代表特定实现与写作时间。应用到当前项目时,应先确认浏览器、框架或工具的主版本,再区分稳定的规范语义、可变化的内部实现和项目自身约束。
# 一、前言
从问题说起:熟悉
React组件生命周期的话都知道:调用setState方法总是会触发render方法从而进行vdom re-render相关逻辑,哪怕实际上你没有更改到Component.state
this.state = {count: 0}
this.setState({count: 0});// 组件 state 并未被改变,但仍会触发 render 方法
- 为了避免这种性能上的浪费,
React提供了一个shouldComponentUpdate来控制触发vdom re-render逻辑的条件。于是PureRenderMixin作为一种优化技巧被使用。它仅仅是浅比较对象,深层次的数据结构根本不管用
js中的Immutable Data
在
javascript中我们可以通过deep clone来模拟Immutable Data,就是每次对数据进行操作,新对数据进行deep clone出一个新数据
- deep clone
- 当然你或许意识到了,这样非常的慢
'use strict';
var cloneDeep = require('lodash.clonedeep');
var data = {
id: 'data',
author: {
name: 'mdemo',
github: 'https://github.com/demohi'
}
};
var data1 = cloneDeep(data);
console.log('equal:', data1===data); //false
data1.id = 'data1';
data1.author.name = 'demohi';
console.log(data.id);// data
console.log(data1.id);// data1
console.log(data.author.name);//mdemo
console.log(data1.author.name);//demohi
这时候 immutableJS 就派得上用场了
var map1 = Immutable.fromJS({a:1, b:1, c:{b:{c:{d:{e:7}}}}});
var map2 = Immutable.fromJS({a:1, b:1, c:{b:{c:{d:{e:7}}}}});
Immutable.is(map1, map2); // true