Skip to content

Instantly share code, notes, and snippets.

@diegohaz
Forked from KurtGokhan/use-combined-refs-new.ts
Created November 29, 2022 22:01
Show Gist options
  • Save diegohaz/493a2e4dd8cf7b3b6ae8b87ba08c35fc to your computer and use it in GitHub Desktop.
Save diegohaz/493a2e4dd8cf7b3b6ae8b87ba08c35fc to your computer and use it in GitHub Desktop.
useCombinedRefs - Old and new
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);
}
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