useForkRef Hook
This hook allows you multiple refs into a single callbackRef.
import React, { MutableRefObject, Ref, RefCallback, useMemo } from 'react';
const setRef = <T>(
ref:
| MutableRefObject<T | null>
| ((instance: T | null) => void)
| null
| undefined,
value: T | null,
) => {
if (typeof ref === 'function') {
ref(value);
} else if (ref) {
ref.current = value;
}
};
/**
* This will create a new function if the refs passed to this hook change and are all defined.
* This means react will call the old forkRef with `null` and the new forkRef
* with the ref. Cleanup naturally emerges from this behavior.
*/
const useForkRef = <T>(
...refs: Array<Ref<T> | undefined>
): RefCallback<T> | null => {
return useMemo(() => {
if (refs.every((ref) => ref == null)) {
return null;
}
return (instance) => {
refs.forEach((ref) => {
setRef(ref, instance);
});
};
}, [refs]);
};
export default useForkRef;
// --- Usage
const componentRef = useForkRef(canvasRef, ref);
return <canvas ref={componentRef} {...other} />;