Skip to content

Instantly share code, notes, and snippets.

@theptrk
Created September 23, 2021 14:39
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 theptrk/45d024efadbad48f1aa2e2cdbcb87d57 to your computer and use it in GitHub Desktop.
Save theptrk/45d024efadbad48f1aa2e2cdbcb87d57 to your computer and use it in GitHub Desktop.
react click outside of container / form
// answer comes from: https://stackoverflow.com/questions/32553158/detect-click-outside-react-component/54292872#54292872
// this adds typescript and I've used this for a form
/*
Custom Hook
*/
function useOuterClick(callback: any) {
const innerRef = useRef() as React.MutableRefObject<HTMLInputElement>;
const callbackRef = useRef() as React.MutableRefObject<HTMLInputElement>;
// set current callback in ref, before second useEffect uses it
useEffect(() => {
// useEffect wrapper to be safe for concurrent mode
callbackRef.current = callback;
});
useEffect(() => {
document.addEventListener("click", handleClick);
return () => document.removeEventListener("click", handleClick);
// read most recent callback and innerRef dom node from refs
function handleClick(e: any) {
if (
innerRef.current &&
callbackRef.current &&
!innerRef.current.contains(e.target)
) {
// @ts-expect-error
callbackRef.current(e);
}
}
}, []); // no need for callback + innerRef dep
return innerRef; // return ref; client can omit `useRef`
}
function MyForm() {
const innerRef = useOuterClick((e: any) => {
props.handleSave(e, item);
});
return (
<div className="form-container" ref={innerRef}>
<form onSubmit={(e) => props.handleSave(e, item)}>
<input type="text"/>
<button type="submit">Submit</button>
</form>
</div>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment