React Router Dom 6中styled-components封装NavLink出现类名异常
问题重现
用styled-components封装react-router-dom v6的NavLink:
import styled from "styled-components"; import { NavLink as BaseNavLink } from "react-router-dom"; export const StyledNavLink = styled(BaseNavLink)``;
使用时传入动态className函数:
<StyledNavLink className={({ isActive }: any) => (isActive ? "active" : "")} to="/contact" > Contact </StyledNavLink>
最终生成的a标签class属性混入了函数定义:
<a aria-current="page" class="sc-hLseeU befAUD ({ isActive }) => isActive ? "active" : "" active" href="#/contact"> Contact </a>
原因分析
react-router-dom v6的NavLink允许className接收函数,但styled-components在处理传递给基础组件的props时,会将函数类型的className作为字符串直接拼接,而非传递给NavLink让其执行判断逻辑,这和v5的处理逻辑不同,导致异常。
解决方案
方案1:使用styled-components的attrs方法绑定className
利用attrs方法获取NavLink的isActive状态,动态设置class:
import styled from "styled-components"; import { NavLink as BaseNavLink, NavLinkProps } from "react-router-dom"; export const StyledNavLink = styled(BaseNavLink).attrs((props: NavLinkProps) => ({ className: ({ isActive }) => `${props.className || ""} ${isActive ? "active" : ""}`.trim() }))``;
使用时直接传入静态className(如果需要):
<StyledNavLink to="/contact"> Contact </StyledNavLink>
方案2:在styled组件内部直接处理active样式
不需要额外传递className函数,直接在styled里通过&.active或者利用NavLink的isActive props来设置样式:
import styled from "styled-components"; import { NavLink as BaseNavLink } from "react-router-dom"; export const StyledNavLink = styled(BaseNavLink)<{ isActive: boolean }>` /* 普通样式 */ color: #333; text-decoration: none; /* active状态样式 */ ${({ isActive }) => isActive && ` color: blue; text-decoration: underline; `} `;
使用时无需手动处理className:
<StyledNavLink to="/contact"> Contact </StyledNavLink>
方案3:自定义组件包裹NavLink,再传递props
先写一个自定义NavLink组件处理className逻辑,再用styled-components封装:
import styled from "styled-components"; import { NavLink, NavLinkProps } from "react-router-dom"; const CustomNavLink = ({ className, ...props }: NavLinkProps) => { return ( <NavLink {...props} className={({ isActive }) => `${className || ""} ${isActive ? "active" : ""}`.trim()} /> ); }; export const StyledNavLink = styled(CustomNavLink)` /* 你的样式 */ `;
使用方式不变:
<StyledNavLink to="/contact"> Contact </StyledNavLink>
内容的提问来源于stack exchange,提问作者ajm
相关产品推荐
相关产品推荐

