import * as React from "react"; // basically Exclude["ref"], string> type UserRef = | ((instance: T | null) => void) | React.RefObject | null | undefined; type Writable = { -readonly [P in keyof T]: T[P] }; const updateRef = (ref: NonNullable>, value: T | null) => { if (typeof ref === "function") { ref(value); return; } (ref as Writable).current = value; }; // Compose 2 refs and give a single entry ref to // attach to dom node // Very useful when you want to forward ref and // at the same time use a ref internally const useComposedRef = ( libRef: React.MutableRefObject, userRef: UserRef, ) => { const prevUserRef = React.useRef>(); return React.useCallback( (instance: T | null) => { libRef.current = instance; if (prevUserRef.current) { updateRef(prevUserRef.current, null); } prevUserRef.current = userRef; if (!userRef) { return; } updateRef(userRef, instance); }, [userRef], ); }; export default useComposedRef;