网站搜索

reactjs - 如何在 NavLink v6 中布局动态子元素


在 NavLink 中,我正在尝试将 isActive 属性作为函数中的 children 传递,并且让我的链接名称是动态的。

我遇到了多个错误,不确定自己哪里做错了(我刚开始学习 React)。

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 组件上,我得到:

此 JSX 标签的 'children' 属性期望一个类型为 'ReactNode | ((props: { isActive: boolean; }) => ReactNode)' 的单个子元素,但提供了多个子元素。

在 item.name 行我得到:

解析错误:预期符号 ‘)’。

而在关闭的 NavLink 之前的最后一个闭合花括号上,我得到了:

意外的符号。你的意思是 {'}'} 还是 &rbrace;?

答案#1

React 组件应返回单个节点元素。将返回的 JSX 包裹在 React.Fragment 组件中。

示例:

<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>

答案#2

此 JSX 标签的 'children' 属性期望一个类型为 'ReactNode | ((props: { isActive: boolean; }) => ReactNode)' 的单一子元素,但提供了多个子元素。

将 item.icon 和 item.name 包裹在 React.Fragment 中,因为你不能从函数返回多个子元素。例如:

<>
<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}</>