React渲染警告排查:列表子项唯一key prop缺失问题
解决React列表key警告问题
你的代码触发警告的核心原因是子菜单列表的key属性放错了位置:
在渲染子菜单的item.subs.map循环中,你把key={item2.sub}加在了SidebarMenuSubButton组件上,但React要求map返回的列表项最外层元素必须携带唯一key。这里map直接返回的是SidebarMenuSubItem,所以key应该绑定在这个组件上,而非它内部的按钮组件。
另外,外层主菜单的key用item.group虽然当前是唯一的,但用item.id会更符合React推荐的“稳定唯一标识”原则,避免后续group值重复导致的潜在问题。
修正后的代码:
"use client" import Image from "next/image"; import {Lock, KeySquare, BoxIcon, Mailbox, Pencil, Plus, Settings, Trash, ListTodo } from "lucide-react" import { Sidebar, SidebarContent, SidebarGroup, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarMenu, SidebarMenuButton, SidebarMenuItem, SidebarMenuSub, SidebarMenuSubItem, SidebarMenuSubButton, } from "@/components/ui/sidebar" import Link from "next/link"; import {usePathname} from "next/navigation"; // Menu items. const items = [ { id:'123aslk', group: '1', title: "Sistema CEP", url: "../pesquisacep", icon: Mailbox, }, { id:'3498dddd', group: '2', title: "Cumprimentos", url: "#", icon: ListTodo, subs: [ { sub:'2-1', title: "Alvarás", url: "#", icon: KeySquare }, { sub: '2-2', title: "Mandados", url: "#", icon: Lock } ], }, { id:'lkgj3434', group: '3', title: "Configurações", url: "#", icon: Settings, } ] export function AppSidebar() { const pathname = usePathname(); console.log(pathname) return ( <Sidebar className=""> <SidebarHeader className=""> <Link href="/" className="flex items-center"> <Image src="/logo.svg" alt="logo" width="40" height="40"></Image> <span className="font-bold text-slate-200">System</span> </Link> </SidebarHeader> <SidebarContent> <SidebarGroup> <SidebarGroupLabel>Sistema</SidebarGroupLabel> <SidebarGroupContent> <SidebarMenu> {items.map((item) => ( {/* 外层主菜单用item.id作为key更可靠 */} <SidebarMenuItem key={item.id}> <SidebarMenuButton asChild variant="outline"> <Link href={item.url}> <item.icon /> <span>{item.title}</span> </Link> </SidebarMenuButton> {item.subs && ( <SidebarMenuSub key={item.id}> {/* 子菜单的key移到SidebarMenuSubItem上 */} {item.subs.map((item2) => ( <SidebarMenuSubItem key={item2.sub}> <SidebarMenuSubButton asChild > <Link href={item2.url} className="flex gap-1 items-center" > <item2.icon className="h-4 w-4" /> <span>{item2.title}</span> </Link> </SidebarMenuSubButton> </SidebarMenuSubItem> ))} </SidebarMenuSub> )} </SidebarMenuItem> ))} </SidebarMenu> </SidebarGroupContent> </SidebarGroup> </SidebarContent> </Sidebar> ) }
内容的提问来源于stack exchange,提问作者Eduardo Garcia Paiva
相关产品推荐
相关产品推荐

