useMergeRef.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import * as React from 'react';
  2. import { assignRef } from './assignRef';
  3. import { useCallbackRef } from './useRef';
  4. var currentValues = new WeakMap();
  5. /**
  6. * Merges two or more refs together providing a single interface to set their value
  7. * @param {RefObject|Ref} refs
  8. * @returns {MutableRefObject} - a new ref, which translates all changes to {refs}
  9. *
  10. * @see {@link mergeRefs} a version without buit-in memoization
  11. * @see https://github.com/theKashey/use-callback-ref#usemergerefs
  12. * @example
  13. * const Component = React.forwardRef((props, ref) => {
  14. * const ownRef = useRef();
  15. * const domRef = useMergeRefs([ref, ownRef]); // 👈 merge together
  16. * return <div ref={domRef}>...</div>
  17. * }
  18. */
  19. export function useMergeRefs(refs, defaultValue) {
  20. var callbackRef = useCallbackRef(defaultValue || null, function (newValue) {
  21. return refs.forEach(function (ref) { return assignRef(ref, newValue); });
  22. });
  23. // handle refs changes - added or removed
  24. React.useLayoutEffect(function () {
  25. var oldValue = currentValues.get(callbackRef);
  26. if (oldValue) {
  27. var prevRefs_1 = new Set(oldValue);
  28. var nextRefs_1 = new Set(refs);
  29. var current_1 = callbackRef.current;
  30. prevRefs_1.forEach(function (ref) {
  31. if (!nextRefs_1.has(ref)) {
  32. assignRef(ref, null);
  33. }
  34. });
  35. nextRefs_1.forEach(function (ref) {
  36. if (!prevRefs_1.has(ref)) {
  37. assignRef(ref, current_1);
  38. }
  39. });
  40. }
  41. currentValues.set(callbackRef, refs);
  42. }, [refs]);
  43. return callbackRef;
  44. }