reactjs - 使用 UUID 作为列表键会导致 React 中不必要的重新渲染吗?
问题描述
我有一个不包含足够数据来生成唯一键的项目列表。如果我使用 uuid 库生成 ID,单个项目的更改是否也会导致其他项目重新渲染,因为它们的密钥每次都会更改?
const people = [
{
gender: 'male',
firstName: 'david',
},
{
gender: 'male',
firstName: 'david',
},
{
gender: 'male',
firstName: 'joe',
},
]
const renderPeople = () => {
return people.map(person => {
return (
<div key={uuid.v4() /* a new value each time? */ }>
<p>{person.gender}</p>
<p>{person.firstName}</p>
</div>
)
})
}
一段时间后......其中一个大卫改变了
const people = [
{
gender: 'male',
firstName: 'david',
},
{
gender: 'male',
firstName: 'davidzz',
},
{
gender: 'male',
firstName: 'joe',
},
]
解决方案
<div key={uuid.v4()}>
每次都分配新的密钥<div>
,所以没用。
如果数组保持不变,则应在创建数组时生成 UUID。
如果数组发生变化,例如从 HTTP 请求接收到,则将再次生成具有相同内容的元素的 UUID。
为了避免这种情况,key
应该特定于person
实体。在可用于明确性的情况下,始终最好使用内部标识符(数据库 ID)。
如果标识符不可用,key
可能取决于元素内容:
return (
<div key={JSON.stringify(person)}>
<p>{person.gender}</p>
<p>{person.firstName}</p>
</div>
)
在创建数组时对元素进行一次散列会更有效,例如uuid
:
import uuidv3 from 'uuid/v3';
...
for (const person of people) {
person.key = uuidv3(JSON.stringify(person), uuidv3.URL);
}
或使用专用的散列函数,如object-hash
.
请注意,如果存在具有相同内容的元素,散列可能会导致键冲突。
推荐阅读
- javascript - ajax 成功调用控制器方法 laravel 时数据库不更新
- angular - 在 Angular5 中使用来自 highcharts-editor 的 ModalEditor
- c# - 连接时如何放置取消按钮
- java - java - 从任意位置删除数组元素并移动剩余元素
- ibm-cloud - 如何与 SharePoint 上的自定义列表同步
- wpf - RadGridView GridViewSelectColumn 即使在禁用时仍然可选择
- html - 如何使用 Bootstrap4 和/或 flex 将内容居中并设置页脚?
- mysql - 在 Windows 服务器和 Ubuntu 上运行 Mysql 8.0 - 比较
- ios - Swift - 在数组中添加粒度(2 x 2、5 x 5 等)
- python - 在 Raspberry Pi Zero 上安装 chromium 或 Firefox webdriver 的可靠方法