Skip to content

Commit

Permalink
RN: Remove forwardRef from ScrollView (#45197)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #45197

With React 19, `forwardRef` is no longer necessary because `ref` is available on props. However, this only holds true for functional components — not class components.

This eliminates the `forwardRef` invocation in `ScrollView`, while retaining the wrapper component to map `ref` to `scrollViewRef` for the class component. For now...

Changelog:
[Internal]

Reviewed By: javache

Differential Revision: D59091873

fbshipit-source-id: 60afcd441aec82fa050738b5c09083f3a26378d6
  • Loading branch information
yungsters authored and facebook-github-bot committed Jun 27, 2024
1 parent bfc51f9 commit 1341169
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 17 deletions.
31 changes: 15 additions & 16 deletions packages/react-native/Libraries/Components/ScrollView/ScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -649,13 +649,13 @@ export type Props = $ReadOnly<{|
* A ref to the inner View element of the ScrollView. This should be used
* instead of calling `getInnerViewRef`.
*/
innerViewRef?: ForwardedRef<InnerViewInstance>,
innerViewRef?: React.RefSetter<InnerViewInstance>,
/**
* A ref to the Native ScrollView component. This ref can be used to call
* all of ScrollView's public methods, in addition to native methods like
* measure, measureLayout, etc.
*/
scrollViewRef?: ForwardedRef<PublicScrollViewInstance>,
scrollViewRef?: React.RefSetter<PublicScrollViewInstance>,
|}>;

type State = {|
Expand Down Expand Up @@ -1891,11 +1891,9 @@ const styles = StyleSheet.create({
},
});

type ForwardedRef<T> = {current: null | T, ...} | ((null | T) => mixed);

type RefForwarder<TNativeInstance, TPublicInstance> = {
getForwardingRef: (
?ForwardedRef<TPublicInstance>,
?React.RefSetter<TPublicInstance>,
) => (TNativeInstance | null) => void,
nativeInstance: TNativeInstance | null,
publicInstance: TPublicInstance | null,
Expand Down Expand Up @@ -1933,21 +1931,22 @@ function createRefForwarder<TNativeInstance, TPublicInstance>(
return state;
}

/* $FlowFixMe[missing-local-annot] The type annotation(s) required by Flow's
* LTI update could not be added via codemod */
function Wrapper(props, ref: (mixed => mixed) | {current: mixed, ...}) {
// NOTE: This wrapper component is necessary because `ScrollView` is a class
// component and we need to map `ref` to a differently named prop. This can be
// removed when `ScrollView` is a functional component.
function Wrapper({
ref,
...props
}: {
...Props,
ref: React.RefSetter<PublicScrollViewInstance>,
}): React.Node {
return <ScrollView {...props} scrollViewRef={ref} />;
}
Wrapper.displayName = 'ScrollView';
// $FlowFixMe[incompatible-call]
const ForwardedScrollView = React.forwardRef(Wrapper);

// $FlowFixMe[prop-missing] Add static context to ForwardedScrollView
ForwardedScrollView.Context = ScrollViewContext;

ForwardedScrollView.displayName = 'ScrollView';
Wrapper.Context = ScrollViewContext;

module.exports = ((ForwardedScrollView: $FlowFixMe): React.AbstractComponent<
module.exports = ((Wrapper: $FlowFixMe): React.AbstractComponent<
React.ElementConfig<typeof ScrollView>,
PublicScrollViewInstance,
> &
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ exports[`ScrollView renders its children: should deep render when not mocked (pl
onTouchMove={[Function]}
onTouchStart={[Function]}
pagingEnabled={false}
scrollViewRef={null}
sendMomentumEvents={false}
snapToEnd={true}
snapToStart={true}
Expand Down

0 comments on commit 1341169

Please sign in to comment.