⚡ 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
webapp
公众号
开发者导航
切换夜间模式
点击侧边栏上一篇
点击侧边栏下一篇
折叠侧边栏
收起全部