React中如何结合styled-components在Link内切换渲染BarItem组件?
解决方案:根据isActive状态切换styled-components组件
核心思路
无需依赖CSS类名切换样式,直接根据isActive值动态渲染对应的styled组件即可。同时可优化styled-components定义,让选中态组件继承基础组件样式,减少代码重复。
修改后的完整代码
import styled from 'styled-components'; import Link from 'next/link'; import { useRouter } from 'next/router'; // 基础导航项样式 const BarItem = styled.a` position: relative; display: block; height: 3rem; text-decoration: none; cursor: pointer; border: 0; `; // 选中态导航项,继承基础样式并添加选中专属样式 const BarItemSelected = styled(BarItem)` font-weight: 500; color: var(--dark-text-color); filter: invert(1); &:after { content: ''; position: absolute; display: block; width: 100%; height: 5px; background-color: white; border-radius: 5px 5px 0 0; bottom: 0; @media (max-width: 63.8rem) { background-color: #000; top: 0; border-radius: 0 0 5px 5px; } } `; const SmartLink = ({ href, test, children, ...props }) => { const router = useRouter(); const isActive = test ? new RegExp(test, 'g').test(router.pathname) : false; // 根据isActive确定要渲染的组件 const ActiveComponent = isActive ? BarItemSelected : BarItem; return ( <Link href={href} {...props}> <ActiveComponent>{children}</ActiveComponent> </Link> ); };
关键修改点
- styled组件继承:
BarItemSelected通过styled(BarItem)继承基础样式,避免重复编写通用样式代码。 - 动态组件选择:用变量
ActiveComponent存储当前要渲染的组件,简化条件渲染逻辑。 - 移除类名依赖:不再通过
className切换样式,直接通过组件类型实现样式切换,更贴合styled-components的使用习惯。
Next.js 13+ App Router适配方案
若使用App Router(Next.js 13及以上版本),Link组件无需嵌套a标签,可通过asChild属性传递styled组件:
// App Router版本的SmartLink const SmartLink = ({ href, test, children, ...props }) => { const router = useRouter(); const isActive = test ? new RegExp(test, 'g').test(router.pathname) : false; const ActiveComponent = isActive ? BarItemSelected : BarItem; return ( <Link href={href} {...props} asChild> <ActiveComponent>{children}</ActiveComponent> </Link> ); };
内容的提问来源于stack exchange,提问作者Edinaldo pereira
相关产品推荐
相关产品推荐

