useComposedRefs.ts 920 B

1234567891011121314151617181920212223242526272829303132
  1. import { Ref, useCallback } from 'react'
  2. type PossibleRef<T> = Ref<T> | undefined
  3. /**
  4. * Set a given ref to a given value
  5. * This utility takes care of different types of refs: callback refs and RefObject(s)
  6. */
  7. function setRef<T>(ref: PossibleRef<T>, value: T) {
  8. if (typeof ref === 'function') {
  9. ref(value)
  10. } else if (ref !== null && ref !== undefined) {
  11. ;(ref as React.MutableRefObject<T>).current = value
  12. }
  13. }
  14. /**
  15. * A utility to compose multiple refs together
  16. * Accepts callback refs and RefObject(s)
  17. */
  18. export function composeRefs<T>(...refs: PossibleRef<T>[]) {
  19. return (node: T) => refs.forEach((ref) => setRef(ref, node))
  20. }
  21. /**
  22. * A custom hook that composes multiple refs
  23. * Accepts callback refs and RefObject(s)
  24. */
  25. export function useComposedRefs<T>(...refs: PossibleRef<T>[]) {
  26. // eslint-disable-next-line react-hooks/exhaustive-deps
  27. return useCallback(composeRefs(...refs), refs)
  28. }