Deno Fresh框架:导航链接匹配路径名变色遇location未定义问题
解决Fresh框架中导航链接激活态样式问题
问题原因
你写的组件默认是Fresh的服务端组件,而location是浏览器专属API,服务端渲染阶段不存在这个对象,所以会抛出未定义错误。Fresh是服务端优先框架,得用框架提供的方式获取路由信息。
方案一:客户端组件使用useRouter钩子
将NavLink改为客户端组件,利用Fresh提供的useRouter钩子获取当前路由信息,服务端渲染和客户端hydration后都能正常工作:
/** @jsx h */ import { h } from "preact"; import { useRouter } from "$fresh/runtime.ts"; import { tw } from "@twind"; interface NavLinkProps { href: string; children: JSX.Element | string; } const NavLink = ({ href, children }: NavLinkProps) => { const router = useRouter(); const isActive = router.url.pathname === href; const bgClass = isActive ? tw`bg-gray-900` : tw`bg-transparent`; return ( <a href={href} className={tw`px-3 py-2 rounded-md text-sm font-medium text-white ${bgClass}`} > {children} </a> ); }; export default NavLink;
方案二:服务端组件通过传入激活状态
如果要在服务端组件中使用NavLink,可以从页面的Request对象解析当前路径,再把isActive状态作为属性传给组件:
页面组件示例:
/** @jsx h */ import { h } from "preact"; import NavLink from "../components/NavLink.tsx"; export default function Home(req: Request) { const url = new URL(req.url); return ( <nav className={tw`flex gap-2`}> <NavLink href="/" isActive={url.pathname === "/"}>首页</NavLink> <NavLink href="/about" isActive={url.pathname === "/about"}>关于我们</NavLink> </nav> ); }
修改后的NavLink组件:
/** @jsx h */ import { h } from "preact"; import { tw } from "@twind"; interface NavLinkProps { href: string; children: JSX.Element | string; isActive: boolean; } const NavLink = ({ href, children, isActive }: NavLinkProps) => { const bgClass = isActive ? tw`bg-gray-900` : tw`bg-transparent`; return ( <a href={href} className={tw`px-3 py-2 rounded-md text-sm font-medium text-white ${bgClass}`} > {children} </a> ); }; export default NavLink;
两种方案按需选择:如果NavLink需要跨页面复用且自动判断激活状态,选方案一;如果在服务端渲染页面中直接使用,方案二更直接。
内容的提问来源于stack exchange,提问作者Norfeldt
相关产品推荐
相关产品推荐

