在 React Router Dom 6 中将 NavLink 与样式化组件一起使用正在向类添加功能

问题描述 投票:0回答:2

我正在尝试将

styled-components
NavLink
中的
react-router-dom@6
一起使用。

import styled from "styled-components";
import { NavLink as BaseNavLink } from "react-router-dom";

export const StyledNavLink = styled(BaseNavLink)``;

然后使用上面的

StyledNavLink
,如下所示

<Styled.StyledNavLink
  className={({ isActive }:any) => (isActive ? "active" : "")}
  to="/contact"
>
  Contact
</Styled.StyledNavLink>

但是在生成链接时的 UI 中,其类如下所示,

<a aria-current="page" class="sc-hLseeU befAUD ({
 isActive
}) => isActive ? &quot;active&quot; : &quot;&quot; active" href="#/contact">
  Contact
</a>

请检查

<a>
标签的类属性。除了活动类之外,它还具有所有函数定义。

以前在

react-router-dom@5
中从未发生过这种情况,但在迁移到
react-router-dom@6
后却出现了。

演示链接:https://codesandbox.io/s/confident-cori-fmy9zk

reactjs typescript react-router-dom styled-components
2个回答
1
投票

styled-component
styled
实用程序会覆盖
className
属性。它将任何传递的
className
函数字符串化并将其注入到 DOM 中。为了解决这个问题,您需要实现一些自定义逻辑,以将
NavLink
className
逻辑应用到另一个不会被覆盖的道具上,然后将其与
className
注入的常规字符串
styled
道具合并.

NavLink.styled.ts
已重命名为
NavLink.styled.tsx
,因此 TSX 在文件中有效使用。

import styled from "styled-components";
import { NavLink as BaseNavLink } from "react-router-dom";
import type { NavLinkProps as BaseNavLinkProps } from "react-router-dom";

interface NavLinkProps extends BaseNavLinkProps {
  customClassName?:
    | string
    | ((props: {
        isActive: boolean;
        isPending?: boolean;
      }) => string | undefined);
}

const NavLink = ({ customClassName, className, ...props }: NavLinkProps) => {
  const getCustomClassName = (props) => {
    switch (typeof customClassName) {
      case "function":
        return customClassName(props);

      case "string":
        return customClassName;

      default:
        return undefined;
    }
  };

  return (
    <BaseNavLink
      className={(props) =>
        [
          getCustomClassName(props), // NavLink "prop"
          className                  // styled-component "prop"
        ]
          .filter(Boolean)
          .join(" ")
      }
      {...props}
    />
  );
};

export const StyledNavLink = styled(NavLink)<NavLinkProps>``;

使用

StyledNavLink
组件的 UI 将使用
customClassName
属性而不是
className
并传递相同的函数或字符串值。

function App() {
  return (
    <HashRouter>
      <nav>
        <StyledNavLink
          to="/home"
          customClassName={({ isActive }) => (isActive ? "current" : "")}
        >
          Home
        </StyledNavLink>
        <StyledNavLink
          to="/about"
          customClassName={({ isActive }) => (isActive ? "current" : "")}
        >
          About Us
        </StyledNavLink>
        <StyledNavLink
          customClassName="current" // <-- always applied
          to="/contact"
        >
          Contact
        </StyledNavLink>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/home" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<ContactUs />} />
      </Routes>
    </HashRouter>
  );
}

Edit using-navlink-with-styled-component-in-react-router-dom-6-is-adding-function-to


-1
投票

样式化 NavLink 将函数定义添加到类属性的主要原因是样式化组件的工作方式。 styled-components 使用一种名为“标记模板文字”的技术来为组件创建 CSS 样式,这意味着 CSS 样式实际上是 JavaScript 代码,而函数定义是该代码的一部分。 在 React Router Dom v6 中,NavLink 组件现在使用名为 activeClassName 的 prop 来指定在 NavLink 处于活动状态时应用到的类。这意味着类属性中不再需要函数定义,因为 activeClassName 属性会处理它。

这是我更改的代码 import styled from "styled-components"; import { NavLink as BaseNavLink } from "react-router-dom"; export const StyledNavLink = styled(BaseNavLink)` `; const NavLink = ({ to, activeClassName }) => ( <Styled.StyledNavLink className={activeClassName} to={to} > ... </Styled.StyledNavLink> ); export default NavLink;

我认为这将从类属性中删除函数定义,并且 NavLink 的样式将正确。

© www.soinside.com 2019 - 2024. All rights reserved.