Skip to content

Instantly share code, notes, and snippets.

@xantiagoma
Created June 8, 2025 10:38
Show Gist options
  • Save xantiagoma/d2e18aa9e6e95303b52036f46e3d4b08 to your computer and use it in GitHub Desktop.
Save xantiagoma/d2e18aa9e6e95303b52036f46e3d4b08 to your computer and use it in GitHub Desktop.
/**
* Copied from Mongo's https://github.com/mongodb/leafygreen-ui/blob/main/packages/hooks/src/useDynamicRefs/index.ts
* https://github.com/mongodb/leafygreen-ui/blob/main/packages/hooks/README.md#usedynamicrefs
*/
import * as React from 'react';
export interface UseDynamicRefsArgs {
prefix?: string;
}
/** The Map type for a given ref object */
export type RefMap<T> = Map<string, React.RefObject<T>>;
/**
* @internal
*/
export function getGetRef<T>(refMap: RefMap<T>) {
/**
* Returns a ref (or creates a new one) for the provided key
*/
function getRef(): undefined;
function getRef(key: string): React.RefObject<T>;
function getRef(key?: string): React.RefObject<T> | undefined {
if (!key) {
console.error('`useDynamicRefs`: Cannot get ref without key');
return;
}
if (refMap.get(key)) {
return refMap.get(key) as React.RefObject<T>;
}
const ref = React.createRef<T>();
refMap.set(key, ref);
return ref;
}
return getRef;
}
/** The function signature for the function returned by `useDynamicRefs` */
export type DynamicRefGetter<T> = ReturnType<typeof getGetRef<T>>;
/**
* Returns a ref "getter" function for the specified namespace (prefix).
*
* Calling the ref "getter" with a key will return a ref for the given namespace and key
*/
export function useDynamicRefs<T>(
args?: UseDynamicRefsArgs
): DynamicRefGetter<T> {
const prefix = args?.prefix;
const getRef = React.useMemo(
() => {
const refMap: RefMap<T> = new Map<string, React.RefObject<T>>();
const getter = getGetRef<T>(refMap);
return getter;
},
// FIXME:
// eslint-disable-next-line react-hooks/exhaustive-deps
prefix ? [prefix] : []
);
return getRef;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment