博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Immutable学习及 React 中的实践
阅读量:6473 次
发布时间:2019-06-23

本文共 2931 字,大约阅读时间需要 9 分钟。

为什么用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
// 使用Immutablefoo = Immutable.fromJS({a: {b: 1}}); //js对象转成Immutable对象 相反toJs()bar = foo.setIn(['a', 'b'], 2);   // 深层使用 setIn 赋值console.log(foo.getIn(['a', 'b']));  // 使用 getIn 取值,打印 1console.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']); // 6var 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 对象 

转载于:https://www.cnblogs.com/cosyer/p/7367942.html

你可能感兴趣的文章
Spring Security(14)——权限鉴定基础
查看>>
IntelliJ IDEA快捷键
查看>>
【iOS-cocos2d-X 游戏开发之十三】cocos2dx通过Jni调用Android的Java层代码(下)
查看>>
MongoDB的基础使用
查看>>
进程间通信——命名管道
查看>>
LINUX 重定向的知识
查看>>
ssh登陆不需要密码
查看>>
ARP
查看>>
java mkdir()和mkdirs()区别
查看>>
桌面支持--excel自动换行
查看>>
虚拟化--003 vcac licence -成功案例
查看>>
windows server 2003各版本及2008各版本的最大识别内存大小
查看>>
OSChina 周六乱弹 ——揭秘后羿怎么死的
查看>>
centos查找未挂载磁盘格式化并挂载
查看>>
IT人员的职业生涯规划
查看>>
sorry,you must have a tty to run sudo
查看>>
ios开发中使用正则表达式识别处理字符串中的URL
查看>>
项目中的积累,及常见小问题
查看>>
Python类型转换、数值操作(收藏)
查看>>
注释书写格式
查看>>