item.id
当我将密钥设置为a
时,我设置了三个输入标记b
,c
,index
;
当我点击反向时,组件Li将挂载,输入将反转
当我将密钥更改为0
时,当我单击反向时,组件Li更新,输入标记不会更改,
我想知道它是怎么发生的?有没有人知道密钥是如何工作的?
答案 0 :(得分:3)
正如@DuncanThacker解释的那样key
用于标识唯一元素,因此在2个渲染过程之间,React知道元素是新事物还是更新事物。请记住,React会对每个渲染进行差异化,以确定DOM中实际发生了哪些变化。
现在解释一下你所看到的行为:
当我将密钥设置为
item.id
时,我设置了三个输入标记a, b, c
;当我点击反向时,组件Li将挂载,输入将反转
当您使用id
作为key
时,您可以重新排序数组,但React只会在第一次时创建并安装节点。您在===mount===
内输出componentWillUpdate
,这就是您看到误导性输出的原因,但React只更新节点(根据需要移动它们)。内部input
的状态也跟随每个<Li>
组件到其新位置,因为React正确理解<Li>
已移动,而不是简单地重新绘制不同的内容。
当我将密钥更改为
index
时,当我单击反向时,组件Li 更新,输入标签不会改变
当您使用index
key
时,React会有效地将每个渲染过程视为以相同顺序呈现数组,但内容不同,因为每个元素的{{1}无论数组内容的顺序如何,key
都是相同的。这也是内部index
保持在同一位置的原因,即使input
标签以不同的方式呈现位置。 这正是您不应将val
用作index
的原因。
你可以这样说明:
key
<强>阵列:强>
|-----------------------|---------------------|--------------------------|
| Before | After | Change |
|-----------------------|---------------------|--------------------------|
从|-----------------------|---------------------|--------------------------|
| { id: 1, val: "A" } | { id: 3, val: "C" } | Moved from last to first |
| { id: 2, val: "B" } | { id: 2, val: "B" } | None |
| { id: 3, val: "C" } | { id: 1, val: "A" } | Moved from first to last |
|-----------------------|---------------------|--------------------------|
呈现key
:
index
从|-----------------------|---------------------|--------------------------|
| <Li key=0 val="A"> | <Li key=0 val="C"> | Val changed "A" to "C" |
| <Li key=1 val="B"> | <Li key=1 val="B"> | None |
| <Li key=2 val="C"> | <Li key=2 val="A"> | Val changed "C" to "A" |
|-----------------------|---------------------|--------------------------|
呈现key
:
item.id
摘要: 您应始终使用|-----------------------|---------------------|--------------------------|
| <Li key=1 val="A"> | <Li key=3 val="C"> | Moved from bottom to top |
| <Li key=2 val="B"> | <Li key=2 val="B"> | None |
| <Li key=3 val="C"> | <Li key=1 val="A"> | Moved from top to bottom |
|-----------------------|---------------------|--------------------------|
或其他一些独特的元素标识符id
。
另请参阅:https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318
答案 1 :(得分:0)
React使用“key”属性来确定是否呈现组件的全新实例,或者是否更新现有组件。因此,使用item id作为键将意味着不会销毁和重新创建该项的组件。如果您向列表中添加一个新项目,它将创建一个新组件,如果您删除一个项目,它将销毁旧项目,但如果更新项目而不更改其ID,该组件将只更新。
它对动态列表非常有用,因为它减少了挂载组件从呈现一个列表项切换到呈现另一个列表项的奇怪情况,而实际上它应该是一个全新的组件实例。