Skip to content

Instantly share code, notes, and snippets.

@hamzakaya
Created June 18, 2022 13:02
Show Gist options
  • Save hamzakaya/41a71dcfbe9dbfc18126f7b6b386eee5 to your computer and use it in GitHub Desktop.
Save hamzakaya/41a71dcfbe9dbfc18126f7b6b386eee5 to your computer and use it in GitHub Desktop.
import {
useMemo,
useRef,
type MutableRefObject,
type Ref,
type RefCallback,
} from 'react';
const useLifecycleRef = <T extends Element>({
onAttach,
onDetach,
ref,
}: {
onAttach?: (element: T) => void;
onDetach?: (element: T) => void;
ref?: Ref<T>;
}): RefCallback<T> & MutableRefObject<T> => {
const innerRef = useRef<T>(null);
return useMemo(() => {
const callbackRef = ((_ref: T) => {
if (innerRef.current) {
if (onDetach && !_ref) {
onDetach(innerRef.current);
}
} else if (onAttach && _ref) {
onAttach(_ref);
}
innerRef.current = _ref;
if (ref) {
if (typeof ref === 'function') {
ref(_ref);
} else {
(ref as MutableRefObject<T>).current = _ref;
}
}
}) as RefCallback<T> & MutableRefObject<T>;
return Object.defineProperty(callbackRef, 'current', {
set: callbackRef,
get: () => innerRef.current,
});
}, []);
};
export default useLifecycleRef;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment