当前位置: 首页 > 后端技术 > Node.js

React系列的Immutable

时间:2023-04-03 10:14:07 Node.js

原文地址:https://gmiam.com/post/react-...什么是ImmutableData?不可变数据是指一旦创建就无法更改的数据。通过使用不可变数据,我们可以轻松处理数据状态和变化检测等问题,并使我们的程序更具可预测性。?npm安装不可变varImmutable=require('immutable');varmap1=Immutable.Map({a:1,b:2,c:3});varmap2=map1.set('b',50);map1.得到('b');//2map2.get('b');//50大致使用API??//将JSObject和Array深度转换为ImmutableMap和ListImmutable.fromJS({a:{b:[10,20,30]},c:40})//Immutable.List浅层转换const$arr1=Immutable.List([1,2,3]);$arr1.size//=>3//给最后一个赋值const$arr2=$arr1.set(-1,0);//=>List[1,2,0]const$arr3=$arr1.insert(1,1.5);//=>List[1,1.5,2,3]const$arr4=$arr1.clear()//=>List[]const$arr5=$arr1.get(0)//=>1//不可变Mapconst$map1=Immutable.fromJS({a:{b:1},c:2});$map1.size//=>2const$map2=$map1.update('c',()=>3)//=>Map{"a":Map{"b":1},"c":3}const$map3=$map1.updateIn('a.b',()=>3)//=>Map{"a":Map{"b":3},"c":2}const$map4=$map1.merge({d:4})//=>Map{"a":Map{"b":1},"c":2,"d":4}更多可以看这里WhyuseImmutable其实从上面这个简单的例子我们可以看出我们可以在不影响原有数据的情况下重新生成一个新的,JQ提供了$.extend来实现浅拷贝和深拷贝copy,而ES6也提供了native方法Object.assign(浅拷贝),但是实际上我们的数据在大多数情况下是非常复杂的,浅拷贝是不行的,但是深拷贝Immutable的性能是非常高的,因为一般的深拷贝是复制所有的节点,但是Immutable使用的是结构共享,对象树中的一个节点变化只会修改这个节点和受其影响的父节点,其他节点是共享的,大家可以看下图感受下使用itwithReact看看上一章的遗留问题[PureRenderMixin],getInitialState:function(){return{value:{foo:'bar'}}},onClick:function(){this.setState({value:{foo:'bar'}})},渲染:function(){console.log('re-render')return(click)}})由于比较的是两个引用不同的对象,每次都会触发重新渲染,在使用ImmutablevarTest=React.createClass({mixins:[PureRenderMixin],getInitialState:function(){return{value:Map({foo:'bar'})}},onClick:function(){this.setState(({value})=>({value:value.set('foo','bar')}))},render:function(){console.log('re-render')return(click)}})在同时,Immutable会返回相同的引用,所以比较后不会触发父组件重新渲染React.createClass({getInitialState:function(){return{value:{foo:"bar"}};},onClick:function(){varvalue=this.state.value;value.foo+="bar";//反模式!this.setState({value:value});},render:function(){return(

点我
);}});转换后varTest=React.createClass({getInitialState:function(){return{value:Map({foo:"bar"})};},onClick:function(){this.setState(({value})=>({值:value.update('foo',v=>v+'bar')}));},render:function(){return(
点我
);}});可以预见,组件会更新,因为每次ImmutableData变化,都会返回一个新的对象,不会影响原来的对象~