Doolan
Doolan

Reputation: 1641

Next.js Stop Propagation on a nested Link element

I have these tiles that are clickable which while send the user to some external page plus a button inside of the tile that should route the user to some page inside of the site. The problem with this is that when clicking on the button, both events are fired so it sends the user to the external page + navigates to the internal page.

<div
  tabIndex={0}
  role="button"
  onClick={onClick}
>
  <div>
    // some markup
    <Link href={url} passHref>
      <a
        role="button"
        onClick={(e) => sendUserToInternalPageEvent(e)}
      >
        // some text
      </a>
    </Link>
  </div>
</div>

The event for sendUserToInternalPageEvent is using the nextjs event object for the Link component. I'm trying to stop propagation for sendUserToInternalPageEvent but event.stopPropagation() is undefined. The goal is for sendUserToInternalPageEvent to send the user to an internal page while using the nextjs Link element and have onClick send the user to the external page.

Upvotes: 5

Views: 11472

Answers (5)

Eric
Eric

Reputation: 1

To prevent triggering the Link if the button clicked, just add passHref in your Link tag and add the following in your button click listener:

onClick={(evt) => {
   evt.preventDefault();
   evt.nativeEvent.stopImmediatePropagation();
   // your handler
}}

Upvotes: 0

Yogini Bende
Yogini Bende

Reputation: 51

For Nextjs 13, you can use e.preventDefault() before your onClick event

Upvotes: 5

fandasson
fandasson

Reputation: 2403

For me worked a combination of

onClick={(e) => {
   e.stopPropagation();
   e.nativeEvent.preventDefault();
   // your handler
}}

Upvotes: 1

quick007
quick007

Reputation: 333

I would recommend swapping out the link element for a div that has an onClick and uses nextjs' router. For example:

<div onClick={() => router.push("/page")}>
  Content
</div>
  

stopPropagation(e); should then work. Keep in mind that this will remove the autoloading that nextjs normally does for links, which you'll need to re-add yourself.

Upvotes: 0

Doolan
Doolan

Reputation: 1641

I ended up going this route

const stopPropagation = (e) => {
    e.stopPropagation();
    e.nativeEvent.stopImmediatePropagation();
  };
<div
  tabIndex={0}
  role="button"
  onClick={onClick}
>
  <div>
    // some markup
    <Link href={url} passHref>
      <a
        role="button"
        onClick={(e) => {
          stopPropagation(e);
          if (!disabled) onClick(e);
        }}
      >
        // some text
      </a>
    </Link>
  </div>
</div>

Upvotes: 6

Related Questions