React / Immutabel.js 踩坑记录(二) - 有关immutable.js 和 React {key}

有关immutable.js

一、说到 immutable 就得说到 variable(var) 在js中可变性这个特性非常有趣吼,犹记最开始接触js的时候被字符串数组收拾得够呛,var a = b ,修改b居然a也会被修改,实在是让当时我的我难以费解,其实是因为b和a指向的地址相同(当然你也可以说他们是同一对象),无论多少次传递,内存地址不变,就不会有状态的克隆和留存。

而immutable(不变性)就是为了解决这个问题而使用的,他可以帮你避免操作数组时的对原对象的直接操作,从而解决一些麻烦的问题

二、不要迷信immutable,不是一定是个数组就要使用immutable的,如果这个数组里的数据经常会进行多次的迭代更替且数组的层级并不是很深,immutable不仅不能帮你理清代码追踪数据的混乱,反而会大大增大你代码的冗余度和复杂度,甚至会让你有一种在操纵数据库的感觉。

三、如果数组的层级很深,则推荐使用immutable,因为cloneDeep新建一个拷贝对象消耗的性能和内存在层级过深的情况下相当大。

四、在创建immutable对象时尽量少用immutable.Map或者List,嵌套使用fromJS你会发现这是个相当明智的决定,比如下列代码

newItemList = newItemList.set(idx,Immutabel.fromJS({value : item}));

五、在用数组更新immutable对象时一定要使用fromJS转换,否则List在创建时会默认把数组转化为Array对象,抛弃map的key值,作者因为这个问题被逼得看了源码,在setIn的时候会根据keyPath进行深层次的递推寻找,且迭代时所用的方法是一致的且绑定在immutable对象上的,所以要是你的immutable对象中混进了Array这个不是immutable对象的对象,结果你当然就是报错给你看咯。

六、善用 mergeDeep , merge顾名思义就是合并混合啦,mergeDeep会将你数组中的深层数组一并进行合并,在处理单层数组的时候跟merge并没有任何的区别(因为实际上他们同样共用一个collection.merge方法,只不过后者进行了递归使用而已,同理想必你也知道了updataIn和updata的关系了)。

所以你甚至可以为了merge优雅的造key值相同的map进行深层数组中的数据更新,而不是使用循环。

七、API是个好东西 https://facebook.github.io/immutable-js/docs/#/

React{key}

diff算法大家都知道,毕竟不学diff算法就等于白学react,key值在当中充当了相当的作用,虽然他不反应在dom树上,这个值也的确不是交予开发者使用的,因为用this.props.key在子组件里是得不到自己的key值的

一、key值是啥呢,我个人的理解他就是子组件的身份证,在判断子组件是否需要销毁重构的时候,key值就是他唯一可以为自己辩护的东西,无证游民或者对不上号怎么办呢?当然是杀了。

二、key值的唯一性需要开发者自己确保,注意噢,这里的唯一性是在同一父组件下同级的体现的,非同一父组件是不用考虑唯一性的,那么问题来了,要是key值不唯一会怎么样呢,key值相同react会认为是同一组件而只做更新不做销毁处理,如果这个组件下有没有受到变更的元素,那么这个元素是不会更新的。

举个栗子:一个输入框组件

<li>{this.props.value} <input type="text"/></li>

在创建的时候使用数组的forEach进行循环创建,并且给予父组件key值为index

假设数组共有4个元素。调用方法在数组中移除第二个元素,此时React开始通过key值进行对比判断子组件是否需要销毁或者更新

由于原先的第三个元素补齐了第二个元素的位置,导致之前的key = 3 变成了本应被删除的key = 2。此时React认为这两个元素相同,而只做更新,受到更新影响的只有this.props.value所影响的<li>,<input>被认为未改变而未销毁,未更新。

此时li与input错位,程序与预期很明显不符。

三、所以,不要用index做key值,除非你的数组只是为了展示,而不会发生来自index序列值上的重排变动,那么用什么做key呢,我喜欢moment..因为,这个对同一使用者而言,创建元素时是不可能出现相同的时间的。(不要使用moment,点快了照旧是同key,还是用自加的id值吧,设置一个id值只能增加而不能减少,这样不管怎么play都不可能会有相同的key值了)

 

你可以看看作者的react-demo,毕竟看文档不如自己动手,对吧,顺便我还想骗颗星星,若是本文对你有帮助,求颗星星啦

https://github.com/xxx407410849/reactDemo

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值