NextJS中如何通过单选按钮实现页面导航并维持选中状态?
解决NextJS侧边栏导航高亮不持久的问题
当前代码修复方案
你的问题核心是页面跳转后组件重新渲染,单选按钮的选中状态丢失,导致peer-checked样式无法触发。另外React中label的for属性需要改为htmlFor(避免和JS关键字冲突),按以下步骤修改:
- 导入Next.js的路由钩子(App Router用
usePathname,Pages Router用useRouter) - 根据当前路由设置单选按钮的
checked属性 - 修正
label的for为htmlFor
代码示例(App Router)
import { usePathname } from 'next/navigation'; import Link from 'next/link'; import { useState } from 'react'; export default function Sidebar() { const pathname = usePathname(); const [done, setDone] = useState(pathname === '/' ? 'first' : 'second'); return ( <div> <Link href="/"> <input name="connected" id="home" type="radio" className="peer/home" value="first" checked={pathname === '/'} onChange={(e) => setDone(e.target.value)} /> <label htmlFor="home" className="bg-red-500 peer-checked/home:bg-blue-500" > Click me </label> </Link> <br /> <Link href="/trucks"> <input name="connected" id="no" type="radio" className="peer/no" value="second" checked={pathname === '/trucks'} onChange={(e) => setDone(e.target.value)} /> <label htmlFor="no" className="bg-red-500 peer-checked/no:bg-blue-500" > Click here </label> </Link> </div> ); }
代码示例(Pages Router)
import { useRouter } from 'next/router'; import Link from 'next/link'; import { useState } from 'react'; export default function Sidebar() { const router = useRouter(); const [done, setDone] = useState(router.pathname === '/' ? 'first' : 'second'); return ( <div> <Link href="/"> <input name="connected" id="home" type="radio" className="peer/home" value="first" checked={router.pathname === '/'} onChange={(e) => setDone(e.target.value)} /> <label htmlFor="home" className="bg-red-500 peer-checked/home:bg-blue-500" > Click me </label> </Link> <br /> <Link href="/trucks"> <input name="connected" id="no" type="radio" className="peer/no" value="second" checked={router.pathname === '/trucks'} onChange={(e) => setDone(e.target.value)} /> <label htmlFor="no" className="bg-red-500 peer-checked/no:bg-blue-500" > Click here </label> </Link> </div> ); }
更高效的实现思路
用单选按钮实现导航高亮属于冗余方案,直接通过当前路由动态给Link添加样式类是更简洁的写法,无需维护表单状态:
代码示例(App Router)
import { usePathname } from 'next/navigation'; import Link from 'next/link'; export default function Sidebar() { const pathname = usePathname(); return ( <div className="flex flex-col gap-2"> <Link href="/" className={`px-4 py-2 rounded transition-colors ${ pathname === '/' ? 'bg-blue-500 text-white' : 'bg-red-500 text-black' }`} > Click me </Link> <Link href="/trucks" className={`px-4 py-2 rounded transition-colors ${ pathname === '/trucks' ? 'bg-blue-500 text-white' : 'bg-red-500 text-black' }`} > Click here </Link> </div> ); }
优势说明
- 代码更简洁,去掉了冗余的表单元素和状态管理
- 直接基于路由判断样式,避免页面跳转后状态丢失的问题
- 符合NextJS导航组件的常规写法,易于维护和扩展
内容的提问来源于stack exchange,提问作者Zach philipp
相关产品推荐
相关产品推荐

