Как мне передать href в функцию onClick в nextjs?

#reactjs #next.js

#reactjs #next.js

Вопрос:

В следующем коде

 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 делает. Что не так с моим кодом?

Ответ №1:

Вы можете переместить обработчик 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>
  );
}
 

Ответ №2:

обновление ответа для обработки условия гонки между 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>
  );

 

Обратите внимание, что если вы сделаете router.push это сразу после console.log , console.log он не будет показан, поскольку вы перенаправляетесь. Но я полагаю, что вы хотите выполнить дополнительную работу, прежде чем нажимать на пользователя, поэтому вы все равно можете следовать этому подходу.

Комментарии:

1. Я пытался реализовать ваше решение, но я не вижу свой console.log. Это потому, что страница перенаправляет на ссылку и очищает консоль? codesandbox.io/s/nextjs-router-bfk11?file=/pages/index.js:0-541

2. О да, это верно. Я обновлю свой ответ, чтобы справиться с этим случаем

3. Спасибо за редактирование. Но теперь я получаю следующую ошибку: Ошибка: сбой тип реквизита: реквизит href ожидает string или object <Link> , но undefined вместо этого получил. Я попытаюсь пересмотреть ваш код и решить проблему.

4. Добро пожаловать. Поскольку вы перемещаетесь программно, элемент, обрабатывающий щелчок, больше не должен быть a <Link> . Это может быть стиль button или span , например.

Ответ №3:

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 amp;amp; <Logo src={shopData?.logo} loading="lazy" />}
            </a>
    )
 }
 

Ответ №4:

С ноября 2021 года вы можете сделать дочерний элемент функциональным компонентом, чтобы использовать журнал консоли:

 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
 

Понятия не имею, почему это должно быть так.

Ответ №5:

Это определение NextJS для ссылки

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

А затем импортируйте свою собственную ссылку вместо ссылки NextJS!
// NavLink.js

 import ALink from './aLink';

export default function Nav() {
    return (
        <nav>
            <ALink href='/' onClick={() => customOnClick() label='home' }/>
        </nav>
    )
}