在以下代码中
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>
);
每当点击about或posts页面时,我都想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>
);
}
更新答案以处理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-08答案
在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>
)
}
从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>
)
}