如何将 href 传递给 nextjs 中的 onClick 函数?

问题描述 投票:0回答:6

在下面的代码中

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
任何东西。我的代码有什么问题吗?

reactjs next.js
6个回答
28
投票

您可以将 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>
  );
}

6
投票

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>
    )
 }

4
投票

更新答案以处理 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
,因为您正在被重定向。但我相信你想在推送用户之前做一些额外的工作,所以你无论如何都可以遵循这种方法。


4
投票

从 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

不知道为什么需要这样。


1
投票

这是 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>
    )
}

0
投票

最好的解决方案存在

<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>
© www.soinside.com 2019 - 2024. All rights reserved.