Skip to content

How can I smoothly scroll upwards in a React Native FlatList without losing my position even momentarily? #47242

@muninderkaur06

Description

@muninderkaur06

Description

<FlatList
  extraData={postsData.data}
  data={postsData.data}
  ref={postDataRef}
  onScroll={handleScroll}
  onMomentumScrollBegin={() => setInitialRender(false)}
  maintainVisibleContentPosition={{
    minIndexForVisible: 10,
  }}
  initialNumToRender={10}
  onScrollToIndexFailed={(info) => {
    if (isToScroll) {
      const wait = new Promise((resolve) => setTimeout(resolve, 500));
      wait.then(() => {
        if (postDataRef?.current) {
          postDataRef?.current?.scrollToIndex({
            index: info?.index > 0 ? info?.index : 0,
            animated: false,
          });
        }
      });
    }
  }}
  renderItem={renderItems}
  style={{
    backgroundColor: colors.background,
  }}
  keyExtractor={(item: any, index) => index.toString()}
  refreshControl={
    <RefreshControl
      refreshing={loadingOnPull}
      onRefresh={onRefresh}
      tintColor={colors.primary}
      progressViewOffset={headerHeight}
    />
  }
  ListHeaderComponent={
    <FooterLoadingIndicator isHidden={loadingRefresh} />
  }
  onEndReached={onEndReached}
  contentContainerStyle={{
    paddingTop: headerHeight,
    paddingBottom: !locked || isAdmin ? spacing.vl + spacing.xxl : 20,
  }}
  onEndReachedThreshold={0.2}
  ListFooterComponent={
    <FooterLoadingIndicator isHidden={endReachLoader} />
  }
/>
const handleScroll = async ({ nativeEvent }: any) => {
  const { firstReceivedPage, currentReceivedPage } = pageDetail;
  if (!hasMoreItem) return null;

  const { contentOffset, layoutMeasurement, contentSize } = nativeEvent;
  const isScrolledToTop = contentOffset.y < 40 && contentOffset.y > 1;
  const isScrolledToBottom =
    contentOffset.y + layoutMeasurement.height >= contentSize.height;

  if (postsData.data?.length < postsData.total_size) {
    if (isScrolledToTop && scrollContentOffsetY.current > contentOffset.y) {
      if (loadingOnPull == true || loadingRefresh == false) return null;

      setIsToScroll(false);
      setLoadingRefresh(false);
      await getPostsData(firstReceivedPage + 1, false, false);
      setLoadingRefresh(true);
      setIsTop(true);
    }
    scrollContentOffsetY.current = contentOffset.y;
  }
};
    React.useCallback(() => {
      if (isScroll) {
        setTimeout(() => {
          postDataRef?.current?.scrollToIndex({
            index: (postsData?.data?.length - 1) > 0 ? postsData?.data?.length - 1 : 0,
            viewOffset: 100,
          });
        }, 1000);
      }
    }, [isScroll, postsData.data.length]),
  );

I'm encountering an issue where, when I'm on page 3 and scroll up to load the previous page (page 2), the scroll position briefly jumps to the first post on page 2 before returning to the intended last post position. The expected behavior is that no position should be lost—once page 2 is loaded and added to the list, the scroll should seamlessly maintain the position, showing the last post without any jump.

Steps to reproduce

I tried adding every prop but unable to stop this loosing position issue

React Native Version

^0.74.5

Affected Platforms

Runtime - Android, Runtime - iOS

Output of npx react-native info

System:
  OS: Windows 11 10.0.22631
  CPU: (4) x64 11th Gen Intel(R) Core(TM) i3-1115G4 @ 3.00GHz
  Memory: 1.26 GB / 7.75 GB
Binaries:
  Node:
    version: 20.16.0
    path: C:\Program Files\nodejs\node.EXE
  Yarn:
    version: 1.22.21
    path: ~\AppData\Roaming\npm\yarn.CMD
  npm:
    version: 10.8.1
    path: C:\Program Files\nodejs\npm.CMD
  Watchman: Not Found
SDKs:
  Android SDK: Not Found
  Windows SDK: Not Found
IDEs:
  Android Studio: Not Found
  Visual Studio: Not Found
Languages:
  Java: Not Found
  Ruby: Not Found
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.6
    wanted: ^0.74.5
  react-native-windows: Not Found
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: Not found
  newArchEnabled: Not found
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found


### Stacktrace or Logs

```text
No error, only position loosing

Reproducer

https://github.com/vthakur-1995/copy_paste

Screenshots and Videos

https://go.screenpal.com/watch/cZ6uldncDL4

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions