forked from deephaven/web-client-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseMergeRef.ts
More file actions
43 lines (41 loc) · 1.4 KB
/
useMergeRef.ts
File metadata and controls
43 lines (41 loc) · 1.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import {
type LegacyRef,
type MutableRefObject,
type Ref,
type RefCallback,
useMemo,
} from 'react';
/**
* Merge multiple react refs into a single ref callback.
* This can be used to merge callback and object refs into a single ref.
* Merged callback refs will be called while object refs will have their current property set.
* @param refs The refs to merge
* @returns A ref callback that will set the value on all refs
*/
export function mergeRefs<T = unknown>(
...refs: readonly (MutableRefObject<T> | LegacyRef<T> | null | undefined)[]
): RefCallback<T> {
return newRef => {
refs.forEach(ref => {
if (ref != null) {
if (typeof ref === 'function') {
ref(newRef);
} else {
// React marks RefObject as readonly, but it's just to indicate React manages it
// We can still write to its current value
// eslint-disable-next-line no-param-reassign
(ref as React.MutableRefObject<T | null>).current = newRef;
}
}
});
};
}
/**
* Merges multiple refs into one ref that can be assigned to the component.
* In turn all the refs passed in will be assigned when the ref returned is assigned.
* @param refs Array of refs to assign
*/
export function useMergeRef<T>(...refs: readonly Ref<T>[]): RefCallback<T> {
// eslint-disable-next-line react-hooks/exhaustive-deps
return useMemo(() => mergeRefs(...refs), refs);
}