当前位置: 首页 > news >正文

React之旅-05 List Key

每个React的初学者,在调试程序时,都会遇到这样的警告:Warning: Each child in a list should have a unique "key" prop. 如下面的代码:

const list = ['Learn React', 'Learn GraphQL'];const ListWithoutKey = () => (<div><ul>{list.map((item) => (<li>{item}</li>))}</ul></div>
);

这个警告提示我们,需要为列表中的每个元素添加 key 属性。如下面的代码:

const ListWithoutKey = () => (<div><ul>{list.map((item, index) => (<li key={index}>{item}</li>))}</ul></div>
);

使用上面的代码调试时,之前的警告会消失,但其实在其背后,有一个隐式的 bug。当你对列表进行重新排序时,特别是当你添加了非受控的元素,问题就会发生。

如果你的代码如下:

const initialList = ['Learn React', 'Learn GraphQL'];const ListWithUnstableIndex = () => {const [list, setList] = React.useState(initialList);const handleClick = event => {setList(list.slice().reverse());};return (<div><ul>{list.map((item, index) => (<li key={index}><label>{item}</label></li>))}</ul><button type="button" onClick={handleClick}>Reverse List</button></div>);
};

运行你的代码,点击按钮对列表进行重新排序,看样子,一切正常。

可是当你添加了不受控的元素时,假如你的代码如下:

const initialList = ['Learn React', 'Learn GraphQL'];const ListWithUnstableIndex = () => {const [list, setList] = React.useState(initialList);const handleClick = event => {setList(list.slice().reverse());};return (<div><ul>{list.map((item, index) => (<li key={index}><label><input type="checkbox" />{item}</label></li>))}</ul><button type="button" onClick={handleClick}>Reverse List</button></div>);
};

在上述的代码中,checkbox 是非受控元素,当你运行上述的代码时,运行的结果,可能和你相像的不太一致。

// 列表最初的样子[x] Learn React
[ ] Learn GraphQL// 点击按钮,列表重新排序后的样子[x] Learn GraphQL
[ ] Learn React

这种结果显然不是你想要的,那这背后终究发生了什么呢?

// 列表当初的样子[x] Learn React (index = 1)
[ ] Learn GraphQL (index = 2)// 点击按钮,列表重新排序后的样子[x] Learn GraphQL (index = 1)
[ ] Learn React (index = 2)

那如何解决这个问题呢,办法当然有,这次,我们使用了相当稳定的元素作为 key 属性。代码如下:

const initialList = [{ id: 'a', name: 'Learn React' },{ id: 'b', name: 'Learn GraphQL' },
];const ListWithStableIndex = () => {const [list, setList] = React.useState(initialList);const handleClick = event => {setList(list.slice().reverse());};return (<div><ul>{list.map(item => (<li key={item.id}><label><input type="checkbox" />{item.name}</label></li>))}</ul><button type="button" onClick={handleClick}>Reverse List</button></div>);
};

点击按钮,列表重新排序后,背后发生了变化。

// 列表最初的样子
[x] Learn React (id = a)
[ ] Learn GraphQL (id = b)// 点击按钮,列表重新排序后的样子[ ] Learn GraphQL (id = b)
[x] Learn React (id = a)

在这里,我们使用了 id 作为 key 属性,当然,你也可以使用列表中的其他元素,但前提是这个元素是不可改变的唯一值。

不管怎样,仍然值得注意的是,只要你的列表保持的顺序或大小没有改变,使用索引是可以的。然后,列表中每个项目的位置不会改变——它与索引一样稳定——因此使用索引是可以的。

原文链接:Why do we need a React List Key

http://www.dtcms.com/a/273541.html

相关文章:

  • 进制转换原理与实现详解
  • cyvcf2 知识点详解
  • MYSQL C_API使用全解
  • 基于gitlab 构建CICD发布到K8S 平台
  • Java大厂面试实录:谢飞机的电商场景技术问答(Spring Cloud、MyBatis、Redis、Kafka、AI等)
  • 飞算Java AI:专为 Java 开发者打造的智能开发引擎
  • 后台管理系统-权限管理
  • 云、实时、时序数据库混合应用:医疗数据管理的革新与展望(下)
  • 从Markdown到PPT:用Python打造专业演示文稿转换器
  • 2025前端面试真题以及答案-不断整理中,问题来源于牛客真题
  • 面具贴纸美颜SDK如何集成进直播APP?技术细节与性能优化实战
  • 百度2026届校招开启,大规模发力AI的百度未来何在?
  • PPT处理控件Aspose.Slides教程:使用 C# 将 PPTX 转换为 EMF
  • 【Linux仓库】命令行参数与环境变量【进程·伍】
  • 语音对话秒译 + 视频悬浮字 + 相机即拍即译:ViiTor 如何破局跨语言场景?
  • Django快速入门搭建网站
  • Monorepo 与包管理工具:从幽灵依赖看 npm 与 pnpm 的架构差异
  • Django母婴商城项目实践(二)
  • 行测之地理常识
  • Linux进程间通信--命名管道
  • 用TensorFlow进行逻辑回归(一)
  • AI 产品经理必看:神秘技术架构图如何打通跨团队沟通壁垒?
  • wpf Canvas 导出图片
  • 利用Claude code,只用文字版系统设计大纲,就能轻松实现系统~
  • AIC8800M40低功耗wifi在ARM-LINUX开发板上做OTA的调试经验
  • 【计算机网络】王道考研笔记整理(2)物理层
  • Flask 入门到实战(2):使用 SQLAlchemy 打造可持久化的数据层
  • Java-70 深入浅出 RPC Dubbo 详细介绍 上手指南
  • QT控件 使用QtServer系统服务实现搭建Aria2下载后台服务,并使用Http请求访问Json-RPC接口调用下载退出
  • 和鲸社区深度学习基础训练营2025年关卡4