-
-
Save diegohaz/493a2e4dd8cf7b3b6ae8b87ba08c35fc to your computer and use it in GitHub Desktop.
useCombinedRefs - Old and new
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ForwardedRef, useCallback } from 'react'; | |
type OptionalRef<T> = ForwardedRef<T> | undefined; | |
type Cleanup = (() => void) | undefined | void; | |
function setRef<T>(ref: OptionalRef<T>, value: T): Cleanup { | |
if (typeof ref === 'function') { | |
const cleanup = ref(value); | |
if (typeof cleanup === 'function') { | |
return cleanup; | |
} | |
return () => ref(null); | |
} | |
else if (ref) { | |
ref.current = value; | |
return () => ref.current = null; | |
} | |
} | |
export function useCombinedRefs<T>(...refs: OptionalRef<T>[]) { | |
return useCallback((value: T | null) => { | |
const cleanups: Cleanup[] = []; | |
for (const ref of refs) { | |
const cleanup = setRef(ref, value); | |
cleanups.push(cleanup); | |
} | |
return () => { | |
for (const cleanup of cleanups) { | |
cleanup?.(); | |
} | |
}; | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, refs); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ForwardedRef, useCallback, useRef } from 'react'; | |
type OptionalRef<T> = ForwardedRef<T> | undefined; | |
function setRef<T>(ref: OptionalRef<T>, value: T) { | |
if (typeof ref === 'function') { | |
ref(value); | |
} else if (ref) { | |
ref.current = value; | |
} | |
} | |
export function useCombinedRefs<T>(...refs: OptionalRef<T>[]) { | |
const previousRefs = useRef<OptionalRef<T>[]>([]); | |
return useCallback((value: T | null) => { | |
let index = 0; | |
for (; index < refs.length; index++) { | |
const ref = refs[index]; | |
const prev = previousRefs.current[index]; | |
// eslint-disable-next-line eqeqeq | |
if (prev != ref) setRef(prev, null); | |
setRef(ref, value); | |
} | |
for (; index < previousRefs.current.length; index++) { | |
const prev = previousRefs[index]; | |
setRef(prev, null); | |
} | |
previousRefs.current = refs; | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, refs); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment