Skip to content

fix(switch): forward ref to the root view - #5065

Open
giaBaoJS wants to merge 1 commit into
callstack:mainfrom
giaBaoJS:fix/switch-forward-ref
Open

fix(switch): forward ref to the root view#5065
giaBaoJS wants to merge 1 commit into
callstack:mainfrom
giaBaoJS:fix/switch-forward-ref

Conversation

@giaBaoJS

Copy link
Copy Markdown

Motivation

Switch accepts no ref. Props does not declare one, the component signature never destructures one, and the root <View style={[styles.wrapper, style]}> is not given one — so ref.current stays null and there is no way to measure() or otherwise reach the switch's host view.

This looks like a leftover from the Reanimated/Pressable rewrite: the surrounding components carry the prop over correctly (Appbar/AppbarBackAction.tsx, FAB/Extended.tsx, Surface.tsx, List/ListItem.tsx, TouchableRipple), Switch just did not.

Scope / correction to the issue

#3729 names both Avatar and Switch. I checked Avatar and it is not affected: AvatarText, AvatarIcon and AvatarImage all spread ...rest onto their root View, so a ref passed to them does land on the host view (I verified ref.current is non-null for all three). Their Props types just do not advertiseref, which is a typing gap rather than a runtime bug — happy to add the declarations in a follow-up if you want.

So this PR only fixes Switch. It does not close#3729 on its own, since that issue asks for the whole surface. One thing I did notice while looking: Banner.tsx declares ref?: React.RefObject<View> in its Props but never uses the value, so Banner drops refs too — again, happy to do that separately.

Note on the ref type

Peers use ref?: React.Ref<View>, but those all forward to a component whose props already carry React.RefAttributes<View> (Animated.View, Pressable, TouchableRipple). Switch's root is a plain <View>, and putting a React.Ref<View> on it fails yarn typecheck:

src/components/Switch/Switch.tsx(351,11): error TS2769: No overload matches this call.
Type 'import(".../node_modules/@types/react/index").Ref<View> | undefined' is not
assignable to type 'React.Ref<View> | undefined'.
... Two different types with this name exist, but they are unrelated.

tsc -b also builds docs/, which has its own copy of @types/react (same version, separate directory), and the unique symbol behind VoidOrUndefinedOnly in the callback-ref signature does not unify across the two copies. React.RefObject<View | null> is structural and unaffected, matches what React.createRef<View>() and useRef<View>(null) produce, and follows the existing declaration in Banner.tsx. Glad to switch it to React.Ref<View> if you'd rather fix the duplicate-types setup instead.

Test plan

Two cases added to src/components/__tests__/Switch.test.tsx:

  • ref.current is not null
  • ref.current.measure is a function (i.e. it is the host view, not some other object)

Both fail before the change (Received: null / Received: "undefined") and pass after.

yarn test: 55 suites, 737 passed / 1 skipped, 169 snapshots — no snapshot churn. yarn lint and yarn typecheck clean.

Refs #3729.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Not all componetns can receive ref

1 participant

@giaBaoJS