前言:( ⊙ o ⊙ )啊!最近简历投得很不顺利呀,感觉是项目经验不符合互联网公司的需求........╮(╯▽╰)╭没办法,在公司做得最多的就是业务逻辑的代码,虽然知道这一点,自己在加紧学习,但是结果还是不尽如人意,毕竟没做过真正的项目别人是很少会"冒险".......也罢,《盗钥匙的方法》中的”杀手“成了我目前的一个”精神“支柱!
在参考官网的文档学习React中,其实有关于key的讲解,但是自己觉得有点晦涩,当时就没怎么看;到后来在做一个例子的时候:商品的表格,提供了简单的查询功能;我在自己实现的过程中,发现”key“这个关键词在react中是比较重要的一个概念,而且后面自己想对价格排序的时候发现在这个"key"上屡屡受挫,只好自己总结一下了。(出来混,总得要还的呀!)
github:https://github.com/liuzaijiang/React-text
我相信大部分人都是参考网上的这篇文章学习的:http://taobaofed.org/blog/2016/08/24/react-key/
一千个读者就有一千个哈姆雷特嘛,我也来学习学习!
首先是概念:
React 元素可以具有一个特殊的属性 key,这个属性不是给用户自己用的,而是给 React 自己用的。如果我们动态地创建 React 元素,而且 React 元素内包含数量或顺序不确定的子元素时,我们就需要提供 key 这个特殊的属性。(大多我们用的地方是渲染数组中的元素,例如表格,li等)
OK,接下来是我根据官网例子加上自己的实现,对于这个key的理解。
在官网,有个例子中就是渲染一个商品的价格表格,你打开F12后会发现:
Warning: flattenChildren(...): Encountered two children with the same key
是因为每个td是放在一个数组中,但是并没有给每个td赋一个唯一的key值属性,解决方法就是:
rows.push(<ProductRow product={product} key={product.name} />);
我这里赋的key是每个商品的name(唯一),不管赋什么都是要保证一个唯一性;(当然还要有一定的技巧性,这个后面操作表格数据的时候会用到。)
这个key值是用来干嘛的呢?
当我们组件状态更新后,会重新渲染组件,渲染组件的时候会一个个去根据key值的情况去渲染:
A. 渲染前的key值存在,则去寻找这个key值对应的组件:
a.组件数据不变,则不重新渲染这个组件;
b.若组件数据改变,则渲染改变的这一部分数据;
B.渲染前的key值不存在,则会销毁这个key值对应的组件:
C.出现新的key值,则渲染一个新的key值对应的组件;
有了上面的这些总结,其实我们就可以对表格进行操作了:增,删,改。
增:
如果想增加一个商品,我们只需要在保存商品的数组中增加这个商品的对象即可,然后为这个数据去添加一个新的key值,这样状态改变的时候就会把这个新商品渲染进表格;
删:
如果想删除一个商品,我们只需要将这个商品在这个数组中去掉,这样key值也会随之没有,渲染的时候这个商品也不会渲染出来;不过我们怎么去寻找到这个商品呢?
这里我们就要利用到key值的一个技巧,上面提到了我给每个商品的 key值赋值的是每个商品的name(唯一),一般都来说都是赋的是index值,就是每个商品在数组中存在的索引值。但是这样不好,为什么?因为我们商品会去排序,这样你的顺序就会被打乱。如果是用name值得话,我们可以很精确的找到,然后配合filter方法来筛选出被删除后的数组。
而且我们是不能通过this.props.key获取这个key值的,所以这里就再为组件定义一个属性,赋值name,这样我们获得这个属性的值,就相当于获得了key值。
流程:首先我们在渲染的时候给每个商品的"删除功能的td元素上"赋值一个name属性,值就是我们的商品name;
然后我们通过click事件的回调函数中的参数event来获取这个name值,event.target.name;
再把这个值在商品的数组中通过filter方法,来筛选出除了这个值的其他商品,这样剩下的就是被删除后的数组,我们需要渲染的商品;
最后更新一下状态,渲染表格;
改:
修改商品和我们删除商品其实大致思路是一样的,只不过稍微多了一些步骤,当我们用filter筛选出了我们需要修改的对象的时候,同时还需要获得它在这个数组中的index(索引),然后再修改其数据,更新状态。
当然,我们修改商品的时候我这边是弹出一个框,然后还需要把商品本身的情况先进行赋值,我们这里需要用到ref这个属性,获取我们真实的DOM节点,比如<input/>这些,但是这里需要注意的就是,ref在render中是无法使用的,因为必须要等组件挂载后才能获取到值,那我们如何为组件预先赋值呢?很简单,使用defaultValue这个属性。
<input ref='modifyCategory' id='staffModifyName' type='text' defaultValue={modifyProduct[0].category}/>这样就行,这个是修改商品,如果是新加商品的话,我们还是用value就行了。
额外:
如果每次渲染的时候想每个组件都刷新(重新渲染)的话,就给这个key值赋一个变量;
rows.push(<ProductRow product={product} key={+new Date() + i} />);
赋一个当前时间加索引,这样每次状态变化的时候,组件都会去重新渲染。
官网提供的那个表格的例子其实比较简陋,还有一个BUG:
let product = [
{category: 'Sporting Goods',price: 49.99,stocked: true,name: 'Football'},
{category: 'Sporting Goods',price: 9.99,name: 'Baseball'},price: 29.99,stocked: false,name: 'Basketball'},
{category: 'Electronics',price: 99.99,name: 'iPod Touch'},price: 399.99,name: 'iPhone 5'},price: 199.99,name: 'Nexus 7'}
];
仔细可以发现,它的商品类别category都是分类好了,按顺序写进了数组,然后表格显示的时候是
Sporting Goods
xxxxx
xxxxx
xxxxx
Electronics
xxxxx
xxxxx
xxxxx
每个商品种类也是一行,这样也会有一个key值,如果把数组的顺序打乱的话,会出现下面这种情况,而且它的商品种类的key都是用的商品的category,这样会出现key值不唯一的情况,我解决了key值不唯一的情况,这个排列有问题的还没有解决,而且做价格排序的话也很有值得思考的地方,到底是按所有商品的价格排序,还是按每个种类的商品排序呢?值得去思考
Sporting Goods
xxxxxx
xxxxxx
Electronics
xxxxxx
xxxxxx
xxxxxx
Sporting Goods
xxxxxx
原文链接:https://www.f2er.com/react/304403.html