I’m using shadcn/ui
in my React Remix app, and I’m trying to prevent it from redirecting to another page when I click to open a dialog. I want the redirection to still work when I click on it, but I want to prevent the page from redirecting when I intend to open the dialog
Codesandbox —-> https://codesandbox.io/p/devbox/shadcn-ui-vite-forked-mptc3y?file=%2Fsrc%2FApp.tsx%3A17%2C2-41%2C13
<div className="flex flex-col border-solid border rounded-md mt-10">
{data.map((item) => {
return (
<div key={item.id}>
<a href={`/inbox/${item.id}`}>
<div className="flex flex-col items-start gap-2 p-3 text-left text-sm transition-all w-full border-b hover:shadow-md cursor-pointer">
<div className="flex w-full flex-col gap-1">
<div className="flex items-center">
<div className="flex items-center gap-2">
<div className="font-semibold">{item.name}</div>
</div>
</div>
</div>
<div className="flex w-full flex-col gap-1">
<div className="flex items-center">
<ApproveDialog id={"some test"} />
</div>
</div>
</div>
</a>
</div>
);
})}
</div>
3
Answers
A
<a>
tag is probably not the best fit for what you are trying to achieve as it is intended to be a hyperlink that navigates elsewhere. Using another tag likebutton
might be a better idea in this case.However, if you really want to stop the
a
tag from navigating away, you may want to include aonClick={ev => ev.preventDefault()}
on thata
tag.Check out ev.preventDefault() documentation.
There’s a reason it is recommended not to place interactive elements like buttons inside/within other interactive elements like anchor tags. You could try stopping the click event propagation of the dialog open button from propagating up the DOMTree and hitting the anchor tag, but I couldn’t get this to work as expected in your sandbox (which I suspect may be due to how the
Dialog
components are implemented).The logical solution is to un-nest these interactive elements so they can function normally as expected in isolation from one another. Refactor the
Inbox
UI a bit to render theApproveDialog
outside the link.Example:
The rendered content remains visually identical, but now the button is rendered outside the link and won’t interfere with navigation when all you are trying to do is open the modal/dialog.
Alternative
Update the logic to make the
Dialog
component fully controlled and totally prevent the default action on theButton
component.Example:
Try bellow code
App.tsx
ApproveDialog.tsx
Update your DialogOverlay as bellow:
(
Dialog.tsx
)