React 之key的使用

key

我遇见的问题

在写项目的时候,项目中需要用到音频播放器,但是原始的 audio 标签在不同的浏览器,会有不同的样式,所以就自己写了一个简单的播放器,用于满足项目中播放音频的功能。
但是在使用的过程中,发现了两个问题:

  • 音频出错的时候怎么提示用户;
  • 在新的音频出现之后,音频组件的状态并没有重置。如下图所示:
    屏幕快照 2018-06-14 下午3.45.43.png

    屏幕快照 2018-06-14 下午3.45.11.png

    第一张图片是查询条件改变后,audio 组件应有的状态和样式,现实确实图二的样子。

解决第一个问题

面对这个问题,我开始的时候是在组件中,给 audio 添加监听 error 事件,因为音频比较多,这样在数据查询条件改变的时候,就要频繁的操作真的DOM,性能比较差,后来发现其实可以在音频播放的时候 catch 错误,提示用户。

const playPromise = audio.play();
        if (playPromise) {
          playPromise.then(() => {}).catch(() => {
            message.error('音频出错了');
          });
        }

解决第二个问题

面对这个问题,想到的就是这个组件并没有卸载重新渲染,而是改变了数据,导致的。
我们知道了问题所在,这样解决起来应该就好很多了。
嗯,我们用 Reactkey 属性来解决这个问题。
那就先来说一下 key 的作用吧:

key 的作用:

react 中的 key 属性,它是一个特殊的属性,它是出现不是给开发者用的,而是给 react 自己用的。
react 利用 key 来识别组件,它是一种身份标识。每个 key 对应一个组件,相同的 keyreact 认为是同一个组件,这样后续相同 key 对应的组件都不会被创建,而是会被传入新的数据,更新组件。
有了 key 属性后,就可以与组件建立了一种对应关系,react 根据 key 来决定是销毁重新创建组件还是更新组件。

  • key 相同,若组件属性有所变化,则 react 只更新组件对应的属性;没有变化则不更新。
  • key 值不同,则 react 先销毁该组件( 有状态组件的componentWillUnmount会执行 ),然后重新创建该组件( 有状态组件的constructor和componentWillUnmount都会执行 )。
key 的使用场景
  • 在项目开发中,key 属性的使用场景最多的还是由数组动态创建的子组件的情况,需要为每个子组件添加唯一的 key 属性值(最好不要用数字的 index 属性 )。那么,为何由数组动态创建的组件必须要用到 key 属性呢?这跟数组元素的动态性有关。
    非数组动态创建的自组件,为什么不需要 key 呢?因为非数组动态创建的自组件,不管 stateprops 怎么变化,其所在的位置都不会发生变化,这是它天然的 key 。而由数组创建的组件可能由于动态的操作导致重新渲染时,子组件的位置发生了变化。
    可以看出,数组创建子组件的位置并不固定,动态改变的;这样有了 key 属性后,react 就可以根据 key 值来判断是否为同一组件。
  • 为一个有复杂繁琐逻辑的组件添加 key 后,后续操作可以改变该组件的 key 属性值,从而达到先销毁之前的组件,再重新创建该组件。
key 其他的注意事项

当然除了为数据元素生成的组件要添加 key ,且 key 要稳定且唯一之外,还需要注意以下几点:

  • key 属性是添加到自定义的子组件上,而不是子组件内部的顶层的组件上。
  • key 值的唯一是有范围的,即在数组生成的同级同类型的组件上要保持唯一,而不是所有组件的 key 都要保持唯一。
  • 不仅仅在数组生成组件上,其他地方也可以使用 key ,主要是react利用 key 来区分组件的,相同的 key 表示同一个组件,react 不会重新销毁创建组件实例,只可能更新; key 不同,react 会销毁已有的组件实例,重新创建组件新的实例。

解决问题,给组件添加 key 属性,如下:

<AudioPlay key={item.requestId} item={item} src={src} type="ASR" idNum={item.id} id={`ASRplay${item.id}`} />
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,179评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,229评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,032评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,533评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,531评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,539评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,916评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,813评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,568评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,654评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,354评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,918评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,152评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,852评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,378评论 2 342

推荐阅读更多精彩内容