Skip to content

fix: fix getNativeScrollRef return type for FlatList#54735

Open
janpe wants to merge 2 commits intofacebook:mainfrom
janpe:improve-flatlist-types
Open

fix: fix getNativeScrollRef return type for FlatList#54735
janpe wants to merge 2 commits intofacebook:mainfrom
janpe:improve-flatlist-types

Conversation

@janpe
Copy link
Copy Markdown

@janpe janpe commented Dec 1, 2025

Summary:

The Problem

When trying to measure the location of a View within a FlatList (ie. for scrolling to the view), the current recommended method is to use measureLayout on the nested view to determine its location inside the containing FlatList:

const MyComponent = () => {
  const flatListRef = useRef<FlatList>(null);
  const nestedViewRef = useRef<View>(null);

  const scrollToNestedView = () => {
    if (!flatListRef.current || !nestedViewRef.current) {
      return;
    }

    nestedViewRef.current.measureLayout(
      flatListRef.current.getNativeScrollRef(),
      (x, y) => { flatListRef.current.scrollTo({ y, animated: true }); },
    );
  }

  return (
    <FlatList ref={flatListRef}>
      <View ref={nestedViewRef}>
        { /* content */ }
      </View>
    </FlatList>
  );
}

However the types for FlatList getNativeScrollRef don't allow this.

The solution

This solution is basically identical to that in #52203. The return value for getNativeScrollRef should be HostInstance | null

Changelog:[GENERAL] [FIXED] - Change FlatList.getNativeScrollRef return type definition to allow accessing the underlying HostInstance.

Test Plan:

None needed. This is only a type update exposing existing functionality.

@meta-cla
Copy link
Copy Markdown

meta-cla Bot commented Dec 1, 2025

Hi @janpe!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Dec 1, 2025
@meta-cla
Copy link
Copy Markdown

meta-cla Bot commented Dec 1, 2025

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@facebook-github-bot facebook-github-bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Dec 1, 2025
@janpe
Copy link
Copy Markdown
Author

janpe commented Dec 3, 2025

@rshest I see you’ve previously reviewed changes on this file. Any chance you could have a look? Thanks!

@janpe
Copy link
Copy Markdown
Author

janpe commented Dec 16, 2025

How about @cipolleschi ? Any change you might have time to take a look at these changes?

@janpe
Copy link
Copy Markdown
Author

janpe commented Mar 18, 2026

@huntie could you maybe look at this small PR? I saw that you've contributed to the code for Lists before so I thought reaching out to you to see if this correction for the types could get merged at some point.

@janpe
Copy link
Copy Markdown
Author

janpe commented Apr 15, 2026

@javache @hoxyq any chance either of you could take a look at this?

| React.ComponentRef<typeof ScrollViewComponent>
| null
| undefined;
getNativeScrollRef: () => HostInstance | null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@janpe This will deviate from our auto-generated types in the Strict API.

Can we check:

  • Is React.ComponentRef<typeof ScrollViewComponent> vs React.ComponentRef<ScrollViewComponent> the fix?
  • Can we update the source code in Flow for FlatList to align?

getNativeScrollRef():
| (null | React.ComponentRef<ScrollViewNativeComponent> | undefined)
| (null | React.ComponentRef<typeof View> | undefined)

| React.ComponentRef<typeof ScrollViewComponent>
| null
| undefined;
getNativeScrollRef: () => HostInstance | null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra note: This needs to be PublicScrollViewInstance, so that it has the extra imperative methods we want.

export interface ScrollViewImperativeMethods {
+getScrollResponder: () => ScrollResponderType;
+getScrollableNode: () => ?number;
+getInnerViewNode: () => ?number;
+getInnerViewRef: () => InnerViewInstance | null;
+getNativeScrollRef: () => HostInstance | null;
+scrollTo: (
options?: ScrollViewScrollToOptions | number,
deprecatedX?: number,
deprecatedAnimated?: boolean,
) => void;
+scrollToEnd: (options?: ?ScrollViewScrollToOptions) => void;

@huntie
Copy link
Copy Markdown
Member

huntie commented May 7, 2026

Hey @janpe, FYI I'm looking at solving a related wider issue in #56673 (fingers crossed, we merge *HostInstance types into all built-in components).

While I'd ideally want us to solve this problem once (for both the current manual TS API and the incoming Strict Flow→TS API), #52203 is indeed precedence.

🚧 Changes needed to land

@huntie huntie self-assigned this May 7, 2026
@janpe janpe force-pushed the improve-flatlist-types branch from 2c6129e to e28a220 Compare May 7, 2026 12:10
@janpe janpe force-pushed the improve-flatlist-types branch from e28a220 to ea01eae Compare May 7, 2026 12:14
@janpe
Copy link
Copy Markdown
Author

janpe commented May 7, 2026

Hey @janpe, FYI I'm looking at solving a related wider issue in #56673 (fingers crossed, we merge *HostInstance types into all built-in components).

While I'd ideally want us to solve this problem once (for both the current manual TS API and the incoming Strict Flow→TS API), #52203 is indeed precedence.

🚧 Changes needed to land

Much appreciated! See my changes and let me know if you'd like to request anything further.

Copy link
Copy Markdown
Member

@huntie huntie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make sure the TS changes pass CI validation!


import * as ReactNativeFeatureFlags from '../../src/private/featureflags/ReactNativeFeatureFlags';
import {type ScrollResponderType} from '../Components/ScrollView/ScrollView';
import {
Copy link
Copy Markdown
Member

@huntie huntie May 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I ask that we omit changes outside the .d.ts files in this PR? I'm actioning these in #56718 🙂

huntie added a commit to huntie/react-native that referenced this pull request May 7, 2026
Summary:
Pull Request resolved: facebook#56718

Update the return type of `getNativeScrollRef` on `ScrollView`, `FlatList`, `SectionList` to be `PublicScrollViewInstance` (previously, a mix of `HostInstance` and `React.ElementRef<>` types which did not include the imperative methods of `ScrollView`).

- This type extends `HostInstance & ScrollViewImperativeMethods`, and is what the `ScrollView` ref chain already returns at runtime.
- The previous types were either too broad (`HostInstance`), wrong (union with `View`), or required `$FlowFixMe` suppressions.

Also removes `ScrollViewNativeComponent` from the public API surface, since it is an internal implementation detail not intended for external use (equivalent props are on the pre-existing `ScrollViewBaseProps` type).

Related to:

- facebook#52203
- facebook#54735

Changelog:
[General][Fixed] - **Strict TypeScript API**: Update `getNativeScrollRef` return type across ScrollView, FlatList, and SectionList

Differential Revision: D104223704
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants