Skip to content

Instantly share code, notes, and snippets.

@jacob-ebey
Last active September 28, 2023 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jacob-ebey/abf4755fe9409c87712aa623bc3396ea to your computer and use it in GitHub Desktop.
Save jacob-ebey/abf4755fe9409c87712aa623bc3396ea to your computer and use it in GitHub Desktop.
Remix Event Delegation
import * as React from "react";
import { useNavigate, useSubmit } from "@remix-run/react";
export function useEventDelegation() {
const navigate = useNavigate();
const submit = useSubmit();
React.useEffect(() => {
const handleClick = (e: MouseEvent) => {
const target = e.target as HTMLElement;
if (
// Only listen to link clicks.
target.tagName !== "A" ||
// Ignore "open in a new tab".
e.metaKey ||
e.ctrlKey ||
e.shiftKey ||
e.altKey
) {
return;
}
const href = target.getAttribute("href");
// Ignore external URLs.
if (
(!href?.startsWith("/") || href?.startsWith("//")) &&
!href?.startsWith("?")
) {
return;
}
e.preventDefault();
navigate(href);
};
const handleSubmit = (e: SubmitEvent) => {
const target = e.target as
| HTMLFormElement
| HTMLButtonElement
| HTMLInputElement;
if (
target.tagName !== "FORM" &&
target.tagName !== "BUTTON" &&
target.tagName !== "INPUT"
) {
return;
}
const form =
target.tagName !== "FORM"
? (target as HTMLFormElement)
: (target as HTMLButtonElement | HTMLInputElement).form;
const preventScrollReset =
target.hasAttribute("data-prevent-scroll-reset") ||
form?.hasAttribute("data-prevent-scroll-reset");
const replace =
target.hasAttribute("data-replace") ||
form?.hasAttribute("data-replace");
e.preventDefault();
submit(target, {
preventScrollReset,
replace,
});
};
addEventListener("click", handleClick);
addEventListener("submit", handleSubmit);
return () => {
removeEventListener("click", handleClick);
removeEventListener("submit", handleSubmit);
};
}, [navigate, submit]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment