Replace useRefObjectAsForwardedRef with useMergedRefs internally#7638
Replace useRefObjectAsForwardedRef with useMergedRefs internally#7638iansan5653 wants to merge 30 commits intomainfrom
useRefObjectAsForwardedRef with useMergedRefs internally#7638Conversation
🦋 Changeset detectedLatest commit: 7349459 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
There was a problem hiding this comment.
Pull request overview
Introduces a new useCombinedRefs hook in @primer/react to safely combine internal and external/forwarded refs (including React 19-style callback ref cleanup), and deprecates useRefObjectAsForwardedRef with migration guidance.
Changes:
- Added
useCombinedRefshook (+ hook docs + unit tests) and exported it from public entrypoints. - Deprecated
useRefObjectAsForwardedRefwith inline migration instructions. - Migrated multiple components from
useRefObjectAsForwardedReftouseCombinedRefs.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/react/src/index.ts | Exports useCombinedRefs from the package root. |
| packages/react/src/hooks/index.ts | Exports useCombinedRefs from the hooks barrel. |
| packages/react/src/hooks/useCombinedRefs.ts | Implements new combined-ref hook with React 18/19 considerations. |
| packages/react/src/hooks/useCombinedRefs.hookDocs.json | Adds docs metadata for the new hook. |
| packages/react/src/hooks/tests/useCombinedRefs.test.tsx | Adds unit tests validating combined ref behavior. |
| packages/react/src/hooks/useRefObjectAsForwardedRef.ts | Deprecates old hook and documents migration. |
| packages/react/src/tests/snapshots/exports.test.ts.snap | Updates export snapshot to include useCombinedRefs. |
| packages/react/src/Button/ButtonBase.tsx | Switches ButtonBase from old ref hook to useCombinedRefs. |
| packages/react/src/Heading/Heading.tsx | Switches Heading from old ref hook to useCombinedRefs. |
| packages/react/src/Link/Link.tsx | Switches Link from old ref hook to useCombinedRefs and removes ref casting. |
| packages/react/src/Dialog/Dialog.tsx | Switches Dialog from old ref hook to useCombinedRefs. |
| packages/react/src/deprecated/DialogV1/Dialog.tsx | Switches deprecated DialogV1 from old ref hook to useCombinedRefs. |
| packages/react/src/Overlay/Overlay.tsx | Switches Overlay from old ref hook to useCombinedRefs. |
| packages/react/src/PageLayout/PageLayout.tsx | Switches PageLayout Pane/Sidebar forwarded refs to useCombinedRefs. |
| packages/react/src/TextInputWithTokens/TextInputWithTokens.tsx | Switches TextInputWithTokens ref forwarding to useCombinedRefs. |
| packages/react/src/Autocomplete/AutocompleteInput.tsx | Switches AutocompleteInput ref forwarding to useCombinedRefs. |
| packages/react/src/Autocomplete/AutocompleteOverlay.tsx | Switches AutocompleteOverlay floating/scroll refs to useCombinedRefs. |
|
🤖 Lint issues have been automatically fixed and committed to this PR. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…react into create-use-combined-refs
francinelucca
left a comment
There was a problem hiding this comment.
Maybe I'm understanding this incorrectly, but how is this different than useMergedRefs? 🤔
useCombinedRefs hook to deprecate and replace useRefObjectAsForwardedRefuseRefObjectAsForwardedRef with useMergedRefs internally
Great callout! I rebuilt this PR on top of another one (#7672) to update |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
After #7672 deprecates
useRefObjectAsForwardedRef, we need to replace internal calls with the new approach, which has several advantages:undefined, a significant DX improvement for using optional React 19 ref props without having to default tonull.However, the new hook is a breaking change from the old one because it returns a combined ref that must be passed to the underlying child component. So I've still left the old hook in place (because it's public) but deprecated it so we can remove it in a future major release.
Internally, we can migrate everything over to the new approach now, which is what I've done in this PR.
useMergedRefsto be React 19 compatible and public + deprecateuseRefObjectAsForwardedRefanduseProvidedRefOrCreate#7672Rollout strategy
Testing & Reviewing
Merge checklist