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

immutability因React官方出镜之使用总结分享!

时间:2023-04-03 12:07:43 Node.js

由于React官方出场的不可变性的使用总结分享!简介  在之前的项目中,遇到了数据复制和引用之间数据层级嵌套太深,复制的值相互影响的问题。后来引入了immutability-helper。分享给大家,至于为什么不是一成不变的,请看下面的分解,这里是@IT·平头哥联盟,我是首席填坑官——苏楠。  相信大家在面试/工作中都遇到过复制js对象/数组的问题。面试官问你,你平时是做什么的??在ES6盛行的当下,ES6一点也不好意思说我是前端(其实我一般都会说我是攻城狮还是抠图幼崽?),我们的第一想法大多如下:Object.assign——最方便;[...]-最引人注目的;JSON.parse、JSON.stringify——完美的组合;$.extend()——jQuery时代引领潮流的前沿API;最后想到的就是递归实现一个;  但是通常我们使用的Object.assign都是浅拷贝。当数据嵌套层级很深时,就会……呵呵;而JSON.parse和stringify应该创建一个可能非常大的临时字符串。然后访问解析器,性能比较慢。所以后来我发现了不可变的“不可变数据”。以前很喜欢,但时间久了,渐渐发现太个性了,凡事都没有商量的余地。所有的数据,从创建、更改、插入、删除等操作都必须遵循它的套路。对于我这样一个终生热爱自由的人来说,长期的束缚是无法忍受的;久违的大概是缘分吧,一天后,在闲逛中遇到了新欢——ImmutabilityHelpers。  好了,今天的话题就是给大家分享ImmutabilityHelpers的一些用法,会介绍API的用法和使用技巧。如有不明白之处欢迎指正:  我太兴奋了,我差点忘了,只是为了添加一个简单的复制://实现一个简单的递归数据复制letcustomClone=(rawObj)=>{letcopyObj={};for(varkeyinrawObj){if(typeofrawObj[key]==='object'&&Object.prototype.toString.call(rawObj[key])!=='[objectArray]'){copyObj[key]=customClone(rawObj[key]);}else{copyObj[key]=rawObj[key];};};返回副本对象;};letobjA={"姓名":"苏南","性别":"男","身高":"176"};让objB=customClone(objA);objB.signature="宝剑锋从磨砺出,梅花香从苦寒来,温暖攻城狮";控制台日志(objA);控制台日志(objB);补充一个Object.assign的坑:letdata={a:1,b:2,children:{name:"苏南",organization:"@IT·平头阁联盟",job:"首席填报官",address:"深圳",age:18}};让data2=Object.assign({},data);data2.children.age=28;data2.children.job="首席工作经理";data2.b=666;console.log("我是原始数据data:",data);console.log("我是复制的数据data2:",data2);immutable上次回顾  都说我有了新欢,忘记了旧爱,但我不是那种无情的人。最后正式介绍一下immutable,为我们的...画上一个完美的句号:  再次声明,我不认为immutable不好或者不够强大,只是个人看法,有些人不喜欢,请不要喷immutable的粉丝,如果想了解更多,可以点这里immutabledataencourages纯函数(数据输入、数据输出)并有助于更简单的应用程序开发和启用函数式编程技术,例如惰性求值。用法示例:constlist1=List([1,2,3]);constlist2=列表([4,5,6]);常量数组=[7,8,9];constlist3=list1.concat(list2,array);console.log(list3)//List{size:9,_origin:0,_capacity:9,_level:5,_root:null,…}不能直接获取数据,必须使用get,--list3.get(0)让数据=fromJS({obj:{}});letdata1={a:1,b:2,children:{name:"苏南",}};让data2=data.mergeIn(['obj'],data1,{c:666});console.log("获取数据:",data2.getIn(['obj','c']));console.log("HereisthedatacreatedbyformJS:",data2.getIn(['obj','children','name']));//使用immutable后,所有数据必须类似于选择器,并且一个一个select,不是说它不够好或者不够强大,而是我不喜欢它类似jQuery选择器的语法,get,getIn,set,List等的用法,当然也可以使用toJS方法转换回来。不变性帮助er出现在gitHub上,它的介绍很简单:Mutateacopyofdatawithoutchangingtheoriginalsource——changethecopyofdatawithoutchangetheoriginalsource。认识它是因为它出现在了react的官方文档中,受到了它的青睐。真的,只是因为在人群中看到了,就念念不忘。它不同于一成不变,不会有那么多条条框框束缚你,给你自由,给你独立的空间,给你独立的思考,让你想用就用,想用就用,用就走。asyouuseit~~(泥马,怎么有点像张小龙说的那个小程序?),不过不用担心,它比小程序坑的少,API也很简单。我们来看看它的基本用法:$push——array;$unshift——数组;$splice——数组;$set——替换/覆盖/合并原始数据;$toggle——字符串数组,切换目标对象的布尔字段列表;$unset——从目标对象中移除数组中的键列表;$merge——合并对象;$apply-将当前值传递给函数并用新的返回值更新它;$add-添加;$remove-删除。以上基本上就是它所有的API。我们来看看具体的用法:$push的使用:看名字就知道它的作用。和原来的推送一样,只是写法有点不同;让arr=[1,2,3,4,5,66];letarr2=update(arr,{$push:["a","b","c"],//必须是[]的形式,不能是"a";[4]:{//!!索引,可以指定修改下标的值$set:"我已经替换了"}});控制台日志(arr2);$unshift的使用:和原来的unshift一样,插入到原来数组的开头,同样的写法是数组的形式;让arr=[1,2,3,4,5,66];letarr2=update(arr,{$unshift:["a","b","c"],[4]:{$set:"我是首席填坑官?苏南"//这个需要注意的是,它的操作是在unshift之前进行的,即在原来的arr上找第四个下标}});console.log("原始数组",arr);//[1,2,3,4,5,66]不会互相影响console.log(arr2);//["a","b","c",1,2,3,4,"我是首席填坑官?苏南",66]$splice的使用:注意:数组集合数组,开始,结束,插入数据...,;让arr=[1,2,3,4,5,66];letarr2=update(arr,{$splice:[[1,2,[66788,99],{a:123,b:"苏南"}]],//or[0,1,"从我开始是插入的内容",88,89,90,"后面可以跟很多,比如数组,对象,字符串"]});控制台日志(arr2);//复杂用法:letobj={name:"immutable",list:[1,2,[90,55,44,3,22,55],3,4,6,7,8]};letobj2=update(obj,{list:{[2]:value=>update(value,{$splice:[[0,2]]//[90,55,44,3,22,55]=>[44,3,22,55]})}});$set的使用:上面已经演示过了。其实就是更换的意思。当有重复的值时,它们将被覆盖。如果没有值,将添加它们以显示更复杂的场景。深层数据不会相互影响;letobj={name:"immutable",children:{address:"ShenZhen",hobby:"@IT·平头哥联盟-前端开发"}};letobj2=update(obj,{$set:{name:"immutability-helper",other:"其他领域,如微信公众号:honeyBadger8,每周为你带来最新分享"}});让obj3=update(obj,{name:{$set:"Sunan"},children:{hobby:{$set:"首席填坑官-javascript"}}});console.log("原始数据:",obj);console.log("obj2:",obj2);console.log("obj3",obj3);$toggle的使用:听名字,应该能猜出切换的意思;Boolean布尔切换,如果你是强制Number类型为0、1,那么在使用reference方法时要注意;letobj={name:"immutable",a:false,b:true,c:1,d:0};让obj2=update(obj,{$toggle:['b','a',"c","d"],});console.log("原始数据:",obj);console.log("obj2:",obj2);$unset的使用:与$set相反,有点remove的味道,但又好像不一样,当操作的对象是object时,删除key;而在数组array中它的值没有了,但是下标保留了下来,数组的长度没有改变。推荐使用$splice删除数组;请看下图:让arr=[1,2,3,4,5,6];letobj={name:"immutable",children:{address:"ShenZhen",hobby:"Blogging"}};letobj2=update(obj,{$unset:["name"],children:{$unset:["address"]}});console.log("原始数据:",obj);console.log("obj2:",obj2);让arr2=update(arr,{$unset:[1]});控制台.log("arr2:",arr2,arr2.lengthH);$merge的使用:$merge和我们最喜欢的Object.assign一样,都是做merge操作,但是比assign好很多,深拷贝,不会互相影响:letarr=[1,2,3,4,5,6];letobj={name:"immutable",children:{地址:"深圳",hobby:"写博客",array:["我不是程序员","我们来了解一下"],}};letobj2=update(obj,{$merge:{arr},children:{array:{$merge:{items:["从前有座山","山中有庙"]},$拼接:[[3,0,"住着小和尚"]]}}});console.log("原始数据:",obj);console.log("obj2:",obj2);$apply使用:$apply根据当前值进行函数运算,得到新值:注意:必须是函数!letobj={name:"immutable",children:{items:["从前有一座山"],array:[1,2,3,4,5,6],}};letobj2=update(obj,{name:{$apply:(val)=>("首席填坑官")},children:{items:{$apply:(val)=>{console.log("老value",val);return[3,0,"Alittlemonthlived"]}},array:{$apply:(val)=>(val.reverse())//必须是函数}}});console.log("原始数据:",obj);console.log("对象2:",obj2);$remove的使用:$remove必须是Set和Map创建的数组:要删除的值必须存在于数组中,如果该值不存在则忽略,$remove:[2,666],2会被删除,6会被忽略;这个api有点奇怪,一个普通数组[],这个不能删除!!;常见错误如下图:letobj={name:“不可变”,children:{array:newSet([1,2,3,4,4]),}};让obj2=update(obj,{children:{array:{$remove:[2],},}});console.log("原始数据:",obj);console.log("obj2:",obj2);$add的使用:$add使用Map/Set就像刚才的$remove一样,$add方法也和es6的Map/Setadd方法一样:写的时候注意,[[]],嵌套!letobj={name:"immutable",array:newMap([["a",1],["b",2]]),};让obj2=update(obj,{array:{$add:[["66",56]],},});console.log("Originaldata:",obj);console.log("obj2:",obj2);console.log("Getkeya:",obj2.array.get('a'));不可变助手的高级用法:你也可以自定义方法,比如定义一个$trinocular方法来判断数组中的值;只是一个简单的例子,更复杂的用法大家可以自行探索。去官方github?update.extend('$trinocular',function(proportion,original){returnoriginal>88?(original/proportion):(proportion+orig复制代码最终);});让数组=[56,33,55,777,322,444,61,12,34,52,245];letarray2=array.map((k,v)=>update(k,{$trinocular:2}))console.log("原始数据:",array);console.log("array2:",array2);Summary/End:以上就是基础API的使用,增加了一些官方的例子,还有没有说到的组合,以及使用过程中可能出现的一些错误,需要注意的地方,更多的定制进阶用法,有兴趣的同学可以自行了解。  以上就是我今天为大家带来的分享。它可能没有immutable那么多的功能,但是它很简洁,没有太多的约束。如有理解错误,欢迎大家指正。毕竟,我还有一个宝贝——新手在路上!?。  下面是我做的公众号,欢迎关注,文章以后会第一时间更新在公众号,原因是之前分享的两篇文章被别人抄袭了公众号?前几天去更新发布的时候,微信提示文章不再原创,检测到同一篇文章,我家宝贝好冷~,果断投诉对方(是培训学校公众号,好生气),还补了还好,掘金放出的链接和截图日期终于胜诉了?!??更多文章:做完小程序项目,老板给我加了6k工资~面试踩过的坑都在这里了~你应该做的前端性能优化总结!如何设置localStorage的过期时间?一步步教你画跑车如何用CSS3画出看得懂你的3D魔方?SVGSprites图标的使用方法作者:苏南-首席填充官链接:https://honeybadger8.github.i...交流:912594095,公众号:honeyBadger8本文为原创,版权归作者所有。商业转载请联系@IT·平头哥联盟获得授权。非商业转载请注明原文链接和出处。