Next JS已分配key仍触发列表子项需唯一key属性警告求助
问题说明
我用Next.js开发项目,侧边栏里加入了自定义折叠面板组件SideAccord.js,通过数组循环渲染数据。明明已经给列表项分配了key属性,却还是收到如下警告:
Warning: Each child in a list should have a unique "key" prop.
Check the render method of SideAccord. See https://reactjs.org/link/warning-keys for more information.
at SideAccord (webpack-internal:///./components/SideAccord/index.js:25:19)
at ul
at div
at div
at nav
at div
at O (webpack-internal:///./node_modules/styled-components/dist/styled-components.browser.esm.js:31:19750)
at Sidebar (webpack-internal:///./components/Sidebar/index.js:28:66)
at div
at Home
at MyApp (webpack-internal:///./pages/_app.js:18:24)
涉及三个组件文件:
Sidebar.jsSideAccord.jsSidebarData.js(存储所有对象和数组形式的数据)
问题排查和解决方法
根据警告提示,问题出在SideAccord组件的渲染逻辑里,哪怕外部循环加了key,也可能存在以下几种情况:
Key未加在循环的最外层元素上
检查SideAccord内部的循环代码,必须把key直接加在map生成的最外层DOM元素或组件上,不能嵌套在子元素中。示例:// 错误:key加在子元素li上 items.map(item => ( <div> <li key={item.id}>{item.name}</li> </div> )) // 正确:key加在循环最外层div上 items.map(item => ( <div key={item.id}> <li>{item.name}</li> </div> ))Key值不唯一
确认SidebarData中的每个数据项都有唯一标识字段(比如id),避免使用数组索引作为key(尤其是数据会动态增删、排序时)。用索引当key会导致React无法正确识别元素变化,仍会触发警告。多层循环遗漏Key
如果SideAccord内部存在多层循环(比如先渲染父菜单,再渲染子菜单),每一层循环都需要分配独立的唯一key。示例:parentItems.map(parent => ( <div key={parent.id}> <h3>{parent.title}</h3> <ul> {/* 子菜单循环必须添加独立key */} {parent.children.map(child => ( <li key={child.id}>{child.name}</li> ))} </ul> </div> ))拆分组件后Key未加在组件上
若将循环的子元素拆分为独立组件,需把key加在该组件上,而非组件内部的元素。示例:// 正确:key加在自定义组件上 items.map(item => <AccordionItem key={item.id} data={item} />) // 错误:仅在组件内部加key,外部循环未加 items.map(item => <AccordionItem data={item} />)
总结
重点检查SideAccord组件内的map循环逻辑,确保每一层循环的最外层元素都配置了唯一且稳定的key值,避免使用索引作为key,同时确认key未嵌套在子元素中。
内容的提问来源于stack exchange,提问作者user19519558

