React Navigation: Scroll to top if tab is the same as active tab

11,456

Solution 1

You can create your tab navigator as follow:

const TabNav = TabNavigator({
   // config
},
{
   navigationOptions: ({ navigation }) => ({
        tabBarOnPress: (scene, jumpToIndex) => {
            // Called when tab is press
        },
    }),
});

In order to scroll to top, you can check this solution:

  1. https://github.com/react-navigation/react-navigation/issues/2955#issuecomment-343422076
  2. https://snack.expo.io/HJp9mEQkG

Solution 2

For who is looking for a solution for react native, if you are using react navigation, you need to import ScrollView, FlatList or SectionList from react-navigation instead of react-native.

eg.

import { FlatList } from 'react-navigation';

You can find the details on the docs: https://reactnavigation.org/docs/4.x/scrollables/

UPDATE

If you are using react navigation v5

import * as React from 'react';
import { FlatList } from 'react-native';
import { useScrollToTop } from '@react-navigation/native';

function CustomComponent() {
  const ref = React.useRef(null);

  useScrollToTop(ref);

  return <FlatList ref={ref} {/* settings */} />;
}

docs: https://reactnavigation.org/docs/use-scroll-to-top

Solution 3

React Navigation 5.x

The simplest solution they have provided is, just pass the ref of your scrollable component to their useScrollToTop hook.

import * as React from 'react';
import { ScrollView } from 'react-native';
import { useScrollToTop } from '@react-navigation/native';

function Albums() {
  const ref = React.useRef(null);

  useScrollToTop(ref);

  return <ScrollView ref={ref}>{/* content */}</ScrollView>;
}

Snack.expo.io Example

Documentation

Solution 4

For react navigation 5, simply use the useScrollToTop hook from @react-navigation/native. Their documentation outlines how to use it here: https://reactnavigation.org/docs/use-scroll-to-top.

From their docs:

Functional Components

import * as React from 'react';
import { ScrollView } from 'react-native';
import { useScrollToTop } from '@react-navigation/native';

function Albums() {
  const ref = React.useRef(null);

  useScrollToTop(ref);

  return <ScrollView ref={ref}>{/* content */}</ScrollView>;
}

Class Components

class Albums extends React.Component {
  render() {
    return <ScrollView ref={this.props.scrollRef}>{/* content */}</ScrollView>;
  }
}

// Wrap and export
export default function(props) {
  const ref = React.useRef(null);

  useScrollToTop(ref);

  return <Albums {...props} scrollRef={ref} />;
}

Sidenote: You can use this on any component that scrolls and has access to the navigation prop. As in, you could have multiple scrollable components under a given screen (if you were using something like react-native-tab-view) and this would work fine for both of them, individually.

Solution 5

tabBarOnPress in navigationOptions. Callback to handle tap events; the argument is an object containing:

the previousScene: { route, index }: the scene which we are leaving. the scene: { route, index } that was tapped. the jumpToIndex method that can perform the navigation for you.

so in your case just use scene object to check which tab is pressed.

check more on react navigation documentation.

Share:
11,456
Fabrizio Giordano
Author by

Fabrizio Giordano

Updated on July 22, 2022

Comments

  • Fabrizio Giordano
    Fabrizio Giordano almost 2 years

    I have a tab-based app. If I'm currently on the first tab, scrolled all the way down, and I click the tab again, I want it to scroll to the top. Is this possible?

    I know I should have a scroll view with a reference and then use this._scrollView.scrollTo(0), but how can I detect when the user taps the tabbar and decide whether it is the same tab?

  • AnBisw
    AnBisw over 4 years
    componentWillMount is deprecated.
  • romadryud
    romadryud about 3 years
    @AnBisw not for now. In the future maybe yes but for now it not deprecated, and you always can use hooks.