在下面的代码中
import Link from "next/link";
export default function IndexPage() {
const handleClick = (path) => {
if (path === "/about") {
console.log("I clicked on the About Page");
}
if (path === "/posts") {
console.log("I clicked on the Posts Page");
}
};
return (
<div>
Hello World.{" "}
<Link onClick={() => handleClick("/about")} href="/about">
<a>About</a>
</Link>
<Link onClick={() => handleClick("/posts")} href="/posts">
<a>Posts</a>
</Link>
</div>
);
每当单击“关于”或“帖子”页面时,我都会
console.log
单击页面名称。现在,我当前的实现没有 console.log
任何东西。我的代码有什么问题吗?
您可以将 onClick 处理程序移至
<a> tag
。
import { useRouter } from "next/router";
import Link from "next/link";
export default function IndexPage() {
const router = useRouter();
const handleClick = (e, path) => {
if (path === "/about") {
console.log("I clicked on the About Page");
}
if (path === "/posts") {
console.log("I clicked on the Posts Page");
}
};
return (
<div>
Hello World.{" "}
<Link href="/">
<a onClick={(e) => handleClick(e, "/about")}>About</a>
</Link>{" "}
<Link href="/">
<a onClick={(e) => handleClick(e, "/posts")}>Posts</a>
</Link>
</div>
);
}
在NextJS,
我做了类似的事
const Nav = () => {
const handleLogoClick = async (e: React.MouseEvent<HTMLAnchorElement, MouseEvent> | undefined, url: string) => {
e?.preventDefault();
alert('clicked');
};
return (
<a href="" onClick={(e) => handleLogoClick(e, '/')}>
{shopData?.logo && <Logo src={shopData?.logo} loading="lazy" />}
</a>
)
}
更新答案以处理 href 和 onClick 之间的竞争条件
由于单击
<Link>
时您会被重定向,因此我不会尝试同时管理 href
和 onClick
。
我会在
handleClick
函数上做所有事情,甚至以编程方式重定向用户:
import { useRouter } from 'next/router'
export default function IndexPage() {
const router = useRouter()
const handleClick = (e, path) => {
e.preventDefault()
if (path === "/about") {
console.log("I clicked on the About Page");
// then you can:
// router.push(path)
}
if (path === "/posts") {
console.log("I clicked on the Posts Page");
// then you can:
// router.push(path)
}
};
}
return (
<div>
Hello World.{" "}
<Link onClick={(e) => handleClick(e, "/about")}>
<a>About</a>
</Link>
<Link onClick={(e) => handleClick(e, "/posts")}>
<a>Posts</a>
</Link>
</div>
);
请注意,如果您在 console.log 之后执行
router.push
,则不会显示 console.log
,因为您正在被重定向。但我相信你想在推送用户之前做一些额外的工作,所以你无论如何都可以遵循这种方法。
从 2021 年 11 月起,您可以让孩子成为一名功能性的 组件,使用控制台日志:
import Link from 'next/link'
// `onClick`, `href`, and `ref` need to be passed to the DOM element
// for proper handling
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
return (
<a href={href} onClick={onClick} ref={ref}>
Click Me
</a>
)
})
function Home() {
return (
<Link href="/about" passHref>
<MyButton />
</Link>
)
}
export default Home
不知道为什么需要这样。
这是 NextJs 对 Link 的定义
declare function Link(props: React.PropsWithChildren<LinkProps>): React.DetailedReactHTMLElement<{
onMouseEnter?: React.MouseEventHandler<Element> | undefined;
onClick: React.MouseEventHandler;
href?: string | undefined;
ref?: any;
}, HTMLElement>;
export default Link;
您可以将自定义 onClick 调用到链接的第一个子项的 onClick 属性。为了使其易于使用,我们可以创建自己的自定义链接来包装 nextJS 的链接。
//aLink.js
import Link from 'next/link'
export default function ALink({ href, onClick, label }) {
return (
<Link href={href}>
<a onClick={() => onClick()}>{label}</a>
</Link>
)
}
然后导入你自己的ALink而不是nextJS的链接! // NavLink.js
import ALink from './aLink';
export default function Nav() {
return (
<nav>
<ALink href='/' onClick={() => customOnClick() label='home' }/>
</nav>
)
}
最好的解决方案存在
<Link
onClick={(e) => {
if (!isPageExist.length) {
e.preventDefault() // if you don't want to navigate
toast.warning('upgrade your plan')
return
} else {
// do what-ever you want before navigating
}
}}
href={item.href}
>
<div>
<div className="flex flex-col">
<p className="font-medium text-md">{item.type}</p>
</div>
</div>
</Link>