React-router-dom v6 NavLink 和 MUI ListItem 不适用于 className

kie*_*kie 8 reactjs react-router material-ui

我在使用 React-router-dom v6 时遇到 MUI 问题。

import ListItem from '@mui/material/ListItem';
import { NavLink } from 'react-router-dom';
Run Code Online (Sandbox Code Playgroud)
<List key={index}>
  <ListItem
     component={NavLink}
     sx={{
       color: '#8C8C8C',
     }}
     to={'/home'}
     className={({ isActive }) => (isActive ? classes.activeLink : undefined)
     >
     <ListItemIcon></ListItemIcon>
   <ListItemText primary='Home'/>
 </ListItem>
</List>
Run Code Online (Sandbox Code Playgroud)

className不工作并显示错误:

No overload matches this call.
  The last overload gave the following error.
    Type '({ isActive }: { isActive: any; }) => boolean' is not assignable to type 'string'
The expected type comes from property 'className' which is declared here on type 'IntrinsicAttributes & { button?: false | undefined; } & ListItemBaseProps & { components?: { Root?: ElementType<any> | undefined; } | undefined; componentsProps?: { ...; } | undefined; } & CommonProps & Omit<...>'
Run Code Online (Sandbox Code Playgroud)

Dre*_*ese 9

问题

问题是classNameprop 是针对 的ListItem,而不是您指定要渲染的组件。它不是无关的 prop,也不会传递给NavLink组件。

解决方案

解决方案似乎是创建一个包含动态className道具的自定义导航链接组件。将动态className函数传递到不同的 prop 上,例如activeClassName,并将其传递给内部的NavLinks classNameprop。

例子:

import { NavLink as NavLinkBase } from 'react-router-dom'; 

const NavLink = React.forwardRef((props, ref) => (
  <NavLinkBase
    ref={ref}
    {...props}
    className={props.activeClassName}
  />
));
Run Code Online (Sandbox Code Playgroud)

...

import ListItem from '@mui/material/ListItem';
import { NavLink } from '../path/to/NavLink';

...

<List key={index}>
  <ListItem
    component={NavLink}
    activeClassName={({ isActive }) =>
      isActive ? classes.activeLink : undefined
    }
    sx={{ color: '#8C8C8C' }}
    to="/home"
  >
    <ListItemIcon></ListItemIcon>
    <ListItemText primary='Home' />
  </ListItem>
</List>
Run Code Online (Sandbox Code Playgroud)

编辑react-router-dom-v6-navlink-and-mui-listitem-not-working-with-classname


kie*_*kie 2

谢谢大家,这是我的解决方案

import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import { Theme } from '@mui/material/styles';
import { createStyles, makeStyles } from '@mui/styles';
import React from 'react';
import { NavLink } from 'react-router-dom';

const MyNavLink = React.forwardRef<any, any>((props, ref) => (
  <NavLink
    ref={ref}
    to={props.to}
    className={({ isActive }) => `${props.className} ${isActive ? props.activeClassName : ''}`}
  >
    {props.children}
  </NavLink>
));

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    activeLink: {
      backgroundColor: '#19ABC0',
      color: '#FFFFFF',
      borderRadius: 8,
      '& .MuiSvgIcon-root': {
        color: '#FFFFFF',
        stroke: '#FFFFFF',
        fill: '#19ABC0',
      },
    },
  })
);

function Sidebar() {
  const classes = useStyles();

  return (
    <>
      <List>
        <ListItem
          component={MyNavLink}
          sx={{
            color: '#8C8C8C',
          }}
          to={'/home'}
          activeClassName={classes.activeLink}
        >
          <ListItemIcon sx={{ stroke: '#8C8C8C', fill: '#FFFFFF' }}></ListItemIcon>
          <ListItemText primary={'Home'} />
        </ListItem>
      </List>
      <List>
        <ListItem
          component={MyNavLink}
          sx={{
            color: '#8C8C8C',
          }}
          to={'/dashboard'}
          activeClassName={classes.activeLink}
        >
          <ListItemIcon sx={{ stroke: '#8C8C8C', fill: '#FFFFFF' }}></ListItemIcon>
          <ListItemText primary={'Dashboard'} />
        </ListItem>
      </List>
    </>
  );
}

Run Code Online (Sandbox Code Playgroud)
className={({ isActive }) => `${props.className} ${isActive ? props.activeClassName : ''}`}
Run Code Online (Sandbox Code Playgroud)

使用MUI的className并添加NavLink的活动类。