Immutable学习及 React 中的实践

为什么用immutable.js呢。有了immutable.js可以大大提升react的性能。

JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。如 foo={a: 1}; bar=foo; bar.a=2 你会发现此时 foo.a 也被改成了 2。虽然这样做可以节约内存,但当应用复杂后,这就造成了非常大的隐患,Mutable 带来的优点变得得不偿失。为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。

而Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享

当state更新时,如果数据没变,也会去做virtual dom的diff,这就产生了浪费。而immutable能优化diff算法的性能。

  • Immmutable collection被当做值对待,而不是对象
  • 任何修改会返回新的immutable collection
  • 几乎所有的Array方法均可用在Immutable.List;几乎所有的Map方法均可用在Immutable.Map;几乎所有的Set方法均可用在Immutable.Set
// 使用Immutable
foo = Immutable.fromJS({a: {b: 1}}); //js对象转成Immutable对象 相反toJs()
bar = foo.setIn([‘a‘, ‘b‘], 2);   // 深层使用 setIn 赋值
console.log(foo.getIn([‘a‘, ‘b‘]));  // 使用 getIn 取值,打印 1
console.log(foo === bar);  //  打印 false
  • 如果js对象想map遍历,可以利用Immutable的Seq高效实现。 
    Seq只执行需要的工作,不会创建Immuntable缓存数组。任何数据可以通过toSeq()转换为lasy Seq格式
var myObject = {a:1,b:2,c:3};
Immutable.Seq(myObject).map(x => x * x).toObject();
// { a: 1, b: 4, c: 9 }
  • Immutable的Map对象和原生js对象可以无痛合并
// 合并merge
var map1 = Immutable.Map({a:1, b:2, c:3, d:4});
var map2 = Immutable.Map({c:10, a:20, t:30});
var obj = {d:100, o:200, g:300};
console.log(map1.merge(map2, obj).toJS()); // Map{}

// Map
  var obj1 = Immutable.Map({a:1, b:2, c:3});
  var obj2 = obj1.set(‘b‘, 50); // set
  console.log(obj1.get(‘b‘),obj2.get(‘b‘)); // get 2 50
  var alpha = Immutable.Map({a:1, b:2, c:3, d:4});
  console.log(alpha.map((v, k) => k.toUpperCase()).join());// ‘A,B,C,D‘

// List
  const list = Immutable.List([ ‘a‘, ‘b‘, ‘c‘ ])
  const result = list.update(2, val => val.toUpperCase())
  console.log("===>",result.toJS())


  • js对象转换为Immutable时,属性都是String类型的。而Immutable.Map接受任何类型,所以get方法不建议使用
var map = Immutable.fromJS(obj);
map.get("1"); // "one"
map.get(1);   // undefined
  • 针对嵌套数据的处理方法,mergeDeep/getIn/setIn/updateIn是最常用的方法。
var nested2 = nested.mergeDeep({a:{b:{d:6}}});
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 6 } } }
nested2.getIn([‘a‘, ‘b‘, ‘d‘]); // 6

var nested3 = nested2.updateIn([‘a‘, ‘b‘, ‘d‘], value => value + 1);
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }

var nested4 = nested3.updateIn([‘a‘, ‘b‘, ‘c‘], list => list.push(6));
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }

react中使用immutable

  getInitialState() {
    return {
      data: Map({ times: 0 })
    }
  },
  handleAdd() {
    this.setState({ data: this.state.data.update(‘times‘, v => v + 1) });
    // 这时的 times 并不会改变
    console.log(this.state.data.get(‘times‘));
  }

immutable+flux

this.state={
searcnfinanceTypeListAll:  Immutable.fromJS([])
}

changeState=()=>{
this.setState({searcnfinanceTypeListAll:Immutable.fromJS(typeList)});
}

建议把 this.state 写成 Immutable 对象

时间: 08-13

Immutable学习及 React 中的实践的相关文章

[转] Immutable 详解及 React 中实践

https://zhuanlan.zhihu.com/p/20295971 作者:camsong链接:https://zhuanlan.zhihu.com/p/20295971来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Shared mutable state is the root of all evil(共享的可变状态是万恶之源) -- Pete Hunt 有人说 Immutable 可以给 React 应用带来数十倍的提升,也有人说 Immutable

react中为什么要使用immutable

因为在react中,react的生命周期中的setState()之后的shouldComponentUpdate()阶段默认返回true,所以会造成本组件和子组件的多余的render,重新生成virtual dom,并进行virtual dom diff,所以解决办法是我们在本组件或者子组件中的shouldComponentUpdate()函数中比较,当不需要render时,不render. 当state中的值是对象时,我们必须使用深拷贝和深比较! 如果不进行深拷贝后再setState,会造成t

React中setState同步更新策略

本文和大家分享的主要是React中setState同步更新相关内容,希望对大家学习React有所帮助. 为了提高性能React将setState设置为批次更新,即是异步操作函数,并不能以顺序控制流的方式设置某些事件,我们也不能依赖于 this.state 来计算未来状态.典型的譬如我们希望在从服务端抓取数据并且渲染到界面之后,再隐藏加载进度条或者外部加载提示: componentDidMount() { fetch('https://example.com') .then((res) => re

深度学习在图像识别中的研究进展与展望

深度学习在图像识别中的研究进展与展望 深度学习是近十年来人工智能领域取得的最重要的突破之一.它在语音识别.自然语言处理.计算机视觉.图像与视频分析.多媒体等诸多领域都取得了巨大成功.本文将重点介绍深度学习在物体识别.物体检测.视频分析的最新研究进展,并探讨其发展趋势. 1.深度学习发展历史的回顾 现在的深度学习模型属于神经网络.神经网络的历史可以追溯到上世纪四十年代,曾经在八九十年代流行.神经网络试图通过大脑认知的机理,解决各种机器学习的问题.1986年Rumelhart.Hinton和Will

【王晓刚】深度学习在图像识别中的研究进展与展望

深度学习是近十年来人工智能领域取得的最重要的突破之一.它在语音识别.自然语言处理.计算机视觉.图像与视频分析.多媒体等诸多领域都取得了巨大成功.本文将重点介绍深度学习在物体识别.物体检测.视频分析的最新研究进展,并探讨其发展趋势. 1. 深度学习发展历史的回顾 现有的深度学习模型属于神经网络.神经网络的历史可追述到上世纪四十年代,曾经在八九十年代流行.神经网络试图通过模拟大脑认知的机理,解决各种机器学习的问题.1986 年Rumelhart,Hinton 和Williams 在<自然>发表了著

Java学习之InputStream中read()与read(byte[] b)

Java学习之InputStream中read()与read(byte[] b) 这两个方法在抽象类InputStream中都是作为抽象方法存在的, JDK API中是这样描述两者的: read() :  从输入流中读取数据的下一个字节,返回0到255范围内的int字节值.如果因为已经到达流末尾而没有可用的字节,则返回-1.在输入数据可用.检测到流末尾或者抛出异常前,此方法一直阻塞. read(byte[] b) :  从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中.以整数形式返回

AspectJ学习笔记2-Eclipse中AspectJ插件AJDT的正确安装方法

接着之前一篇日志.这个事情也挺无语的,简单记录一下. 在这里:http://www.eclipse.org/ajdt/ 可以下载最新的Eclipse Plugin,下载解压之后,一般来说,直接把解压后文件夹下的features和plugins放到Eclipse的文件夹下就行了.不过我这样做以后,启动Eclipse,发现没什么作用.才参考网上有人介绍的第二种方法,也就是Help--Install New Software--Add--Local这种方式选择刚才的解压文件夹,但是这样操作以后会报像下

深入理解react中的虚拟DOM、diff算法

文章结构: React中的虚拟DOM是什么? 虚拟DOM的简单实现(diff算法) 虚拟DOM的内部工作原理 React中的虚拟DOM与Vue中的虚拟DOM比较 React中的虚拟DOM是什么?   虽然React中的虚拟DOM很好用,但是这是一个无心插柳的结果.   React的核心思想:一个Component拯救世界,忘掉烦恼,从此不再操心界面. 1. Virtual Dom快,有两个前提 1.1 Javascript很快  Chrome刚出来的时候,在Chrome里跑Javascript非

《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音

<Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内容主要都是介绍如何在屏幕上显示图像,事实上除了图像之外,音乐的播放也可以被理解为一种显示的方式,本节将学习在Cocos2d-x中播放声音的方法. (1)在HelloWorld.h中对HelloWorld类进行如下定义: class HelloWorld : public Cocos2d::Layer { pu