React Router v6中NavLink动态子元素布局及报错解决
问题场景
在使用NavLink组件时,尝试将接收isActive属性的函数作为children传入,同时实现链接名称的动态渲染,代码编写完成后出现多个解析报错。
原始错误代码
import { NavLink } from 'react-router-dom'; const navigation = [ { name: 'Home', href: '/', icon: HomeIcon, current: true }, { name: 'Users', href: '/Users', icon: UsersIcon, current: false } ] function classNames(...classes: string[]) { return classes.filter(Boolean).join(' ') } export class Nav extends Component<any, any> { constructor(props: boolean) { super(props); } render() { return ( <> <nav className="mt-5 flex-1 px-2 space-y-1"> {navigation.map((item) => ( <NavLink key={item.name} to={item.href} > {({ isActive }) => ( <item.icon className={classNames( isActive ? 'text-gray-300' : 'text-gray-400 group-hover:text-gray-300', 'mr-3 flex-shrink-0 h-6 w-6' )} aria-hidden="true" /> {item.name} )} </NavLink> ))} </nav> </> ); } }
报错信息
NavLink组件位置报错:
This JSX tag's 'children' prop expects a single child of type 'ReactNode | ((props: { isActive: boolean; }) => ReactNode)', but multiple children were provided.
item.name代码行报错:
Parsing error: ')' expected.
</NavLink>前最后一个闭合大括号位置报错:
Unexpected token. Did you mean
{'}'}or}?
问题根因
三个报错是同一个问题触发的连锁反应:NavLink的children render function要求返回单个React根节点,代码中箭头函数直接并列返回了图标组件、文字两个同级元素,没有外层包裹,导致JSX解析器在图标标签闭合后就判定函数返回内容已经结束,后续的文字、闭合符号全部被识别为非法语法。
除此之外代码还存在两个潜在运行时问题:
- 缺少必要导入:没有从
react导入Component,也没有导入HomeIcon、UsersIcon两个图标组件,运行时会触发未定义错误 - 类型标注错误:constructor的props类型错误标注为
boolean,如果不需要额外初始化state、绑定自定义方法,可以直接删除constructor,类组件会自动处理props传递
修复后代码
// 补全缺失的导入 import { Component } from 'react'; import { NavLink } from 'react-router-dom'; // 替换为实际项目中的图标导入路径 import { HomeIcon, UsersIcon } from '@heroicons/react/24/outline'; const navigation = [ { name: 'Home', href: '/', icon: HomeIcon, current: true }, { name: 'Users', href: '/Users', icon: UsersIcon, current: false } ] function classNames(...classes: string[]) { return classes.filter(Boolean).join(' ') } export class Nav extends Component<any, any> { render() { return ( <> <nav className="mt-5 flex-1 px-2 space-y-1"> {navigation.map((item) => ( <NavLink key={item.name} to={item.href} // 可选优化:把NavLink的className也改为基于isActive动态计算,补充group类让hover样式生效 className={({ isActive }) => classNames( isActive ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'group flex items-center px-2 py-2 text-sm font-medium rounded-md' )} > {({ isActive }) => ( // 核心修复:用Fragment包裹多个同级元素,保证返回单个根节点,不会额外生成DOM节点 <> <item.icon className={classNames( isActive ? 'text-gray-300' : 'text-gray-400 group-hover:text-gray-300', 'mr-3 flex-shrink-0 h-6 w-6' )} aria-hidden="true" /> {item.name} </> )} </NavLink> ))} </nav> </> ); } }
内容的提问来源于stack exchange,提问作者Trevor
相关产品推荐
相关产品推荐

