Как отменить переход при клике на вложенный элемент внутри компонента Link в Next.js?

Привет всем! У меня есть карточка, обернутая в тег Link, которая позволяет перейти на определенную страницу. Внутри этой карточки располагается кнопка, по нажатию на которую открывается модальное окно. Как можно предотвратить переход по Link, если я нажимаю на кнопку внутри карточки? 

Вот фрагмент кода из файла page.tsx:

<pre><code class="javascript">import Link from "next/link";

{doubts && doubts.length ? (
          doubts.map((doubt) => (
            <Link href={`/doubt/${doubt.id}`} key={doubt.id}>
              <CardDoubtBlock doubt={doubt} />
            </Link>
          ))
        ) : (
          <p>Нема</p>
        )}</code></pre> 

А вот часть кода внутри компонента cardDoubt:

<pre><code class="javascript">const handleOpenModal = (event: React.MouseEvent) => {
    event.preventDefault();
    event.stopPropagation(); 
    setViewDoubtModal(true);
};

<div className="flex gap-3 items-center">
          <ColorCardElement
            type={doubt.averageReaction}
            className="p-2 rounded-sm md:p-3"
          />
          <div>
            <h3 className="md:text-base">{doubt.title}</h3>
            <p className="text-sm text-secondary">
              Осталось {differenceDayDoubt} дней
            </p>
          </div>
        </div>
        <Button size="sm" onClick={(event) => handleOpenModal(event)}>
          Реакция
        </Button></code></pre> 

Надеюсь, этого достаточно для понимания.
  • 15 декабря 2024 г. 19:23
Ответы на вопрос 1
Чтобы предотвратить переход при клике на кнопку внутри карточки, вам нужно убедиться, что клик на кнопку не вызывает переход по ссылке. Вы уже на правильном пути, используя `event.stopPropagation()`. Это сообщение предотвращает всплытие события клика к родительскому элементу (в вашем случае к `<Link>`).

Вот что вы можете сделать:

1. Убедитесь, что ваша кнопка действительно вызывает обработчик `handleOpenModal`, который вы уже написали.
2. В обработчике `handleOpenModal` используйте `event.preventDefault()` и `event.stopPropagation()`, чтобы предотвратить переход по ссылке.

Ниже приведён пример вашего кода с некоторыми добавлениями:

```javascript
import Link from "next/link";

{doubts && doubts.length ? (
  doubts.map((doubt) => (
    <Link href={`/doubt/${doubt.id}`} key={doubt.id}>
      <CardDoubtBlock doubt={doubt} />
    </Link>
  ))
) : (
  <p>Нема</p>
)}

// Код внутри компонента CardDoubt

const handleOpenModal = (event: React.MouseEvent) => {
  event.preventDefault(); // предотвращаем действия по умолчанию
  event.stopPropagation(); // предотвращаем всплытие события
  setViewDoubtModal(true);
};

return (
  <div onClick={(event) => handleClick(event)}>
    <div className="flex gap-3 items-center">
      <ColorCardElement
        type={doubt.averageReaction}
        className="p-2 rounded-sm md:p-3"
      />
      <div>
        <h3 className="md:text-base">{doubt.title}</h3>
        <p className="text-sm text-secondary">
          Осталось {differenceDayDoubt} дней
        </p>
      </div>
    </div>
    <Button size="sm" onClick={(event) => handleOpenModal(event)}>
      Реакция
    </Button>
  </div>
);
```

### Объяснение:
- В обработчике клика кнопки `handleOpenModal`, вы вызываете `event.preventDefault()` и `event.stopPropagation()` - этого достаточно, чтобы предотвратить переход.
- Убедитесь, что обработчик клика применен именно к кнопке, а не к родительскому элементу `<Link>`, чтобы избежать непреднамеренного перехода.

С таким подходом, нажатие на кнопку будет вызывать модальное окно, и переход по ссылке не произойдет.
Похожие вопросы