From 9fca9020dfb8d1d213dddf1f6e873fd57767edc8 Mon Sep 17 00:00:00 2001 From: Chance Strickland Date: Thu, 12 Dec 2024 17:28:15 -0800 Subject: [PATCH] minor refactor + add comments --- .yarn/versions/6b9a7d73.yml | 3 +++ .../react/compose-refs/src/composeRefs.tsx | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) create mode 100644 .yarn/versions/6b9a7d73.yml diff --git a/.yarn/versions/6b9a7d73.yml b/.yarn/versions/6b9a7d73.yml new file mode 100644 index 000000000..23f22ea83 --- /dev/null +++ b/.yarn/versions/6b9a7d73.yml @@ -0,0 +1,3 @@ +declined: + - primitives + - "@radix-ui/react-compose-refs" diff --git a/packages/react/compose-refs/src/composeRefs.tsx b/packages/react/compose-refs/src/composeRefs.tsx index f943c62d1..667f459a4 100644 --- a/packages/react/compose-refs/src/composeRefs.tsx +++ b/packages/react/compose-refs/src/composeRefs.tsx @@ -18,18 +18,31 @@ function setRef(ref: PossibleRef, value: T) { * A utility to compose multiple refs together * Accepts callback refs and RefObject(s) */ -function composeRefs(...refs: PossibleRef[]) { - return (node: T) => { - const cleanups = refs.map((ref) => setRef(ref, node)); - if (cleanups.some((c) => typeof c == 'function')) { +function composeRefs(...refs: PossibleRef[]): React.RefCallback { + return (node) => { + let hasCleanup = false; + const cleanups = refs.map((ref) => { + const cleanup = setRef(ref, node); + if (!hasCleanup && typeof cleanup == 'function') { + hasCleanup = true; + } + return cleanup; + }); + + // React <19 will log an error to the console if a callback ref returns a + // value. We don't use ref cleanups internally so this will only happen if a + // user's ref callback returns a value, which we only expect if they are + // using the cleanup functionality added in React 19. + if (hasCleanup) { return () => { - cleanups.forEach((cleanup, i) => { + for (let i = 0; i < cleanups.length; i++) { + const cleanup = cleanups[i]; if (typeof cleanup == 'function') { cleanup(); } else { setRef(refs[i], null); } - }); + } }; } }; @@ -39,7 +52,7 @@ function composeRefs(...refs: PossibleRef[]) { * A custom hook that composes multiple refs * Accepts callback refs and RefObject(s) */ -function useComposedRefs(...refs: PossibleRef[]) { +function useComposedRefs(...refs: PossibleRef[]): React.RefCallback { // eslint-disable-next-line react-hooks/exhaustive-deps return React.useCallback(composeRefs(...refs), refs); }