React Native Scrollview: scroll to top on button click

11,526

Solution 1

You could either let the parent hook into the FloatingButton's onPress function or pass the ref down to the FloatingButton directly.

export const Parent : FC<ParentProps> = props => {
    const scrollRef = useRef<ScrollView>();

    const onFabPress = () => {
        scrollRef.current?.scrollTo({
            y : 0,
            animated : true
        });
    }

    return (
        <View>
            <ScrollView ref={scrollRef}>
                {/* Your content here */}
            </ScrollView>
            <FloatingButton onPress={onFabPress} />
        </View>  
    );
}

export const FloatingButton : FC<FloatingButtonProps> = props => {
    const { onPress } = props;

    const onFabPress = () => {
        // Do whatever logic you need to
        // ...

        onPress();
    }

    return (
        <Fab position="bottomRight" onPress={onFabPress}>
            <Icon name="arrow-round-up" />
        </Fab>
    );
}

Solution 2

You should determine the horizontal or vertical value you want to scroll to, like this code snippet.

onPress={()=> 
   this.scroll.current.scrollTo({ x:0, y:0 });
}

Solution 3

Please have a look at my snack code. Hope it might be helpful for you.

https://snack.expo.io/@anurodhs2/restless-edamame
Share:
11,526
RuntimeError
Author by

RuntimeError

Updated on July 09, 2022

Comments

  • RuntimeError
    RuntimeError almost 2 years

    So I have a component with ScrollView which contains many elements, so you have to scroll a long way down.

    Now there should be a button at the bottom of the page that on click will scroll the page back to top.

    I already created the button as a FAB (floating action button) in an extra component.

    It is integrated in a parent component, where the ScrollView is located.

    What I found was that you have to create a ref in the ScrollView component and implement a button right there that uses this ref to make scrolling work. Simplified, here is what I have so far:

    imports ...
    const ParentComponent: React.FC<Props> = () => {
    
      const scroll = React.createRef();
    
      return (
        <View>
          <ScrollView ref={scroll}>
            <SearchResult></SearchResult> // creates a very long list 
            <FloatingButton
              onPress={() => scroll.current.scrollTo(0)}></FloatingButton>
          </ScrollView>
        </View>
      );
    };
    
    export default ParentComponent;
    

    As you can see, there is the component FloatingButton with the onPress() method.

    Here is the implementation:

    import React, {useState} from 'react';
    import {Container, Content, Button, Icon, Fab} from 'native-base';
    
    const FloatingButton: React.FC<Props> = () => {
    
      return (
        <Fab
          position="bottomRight"
          onPress={(???}>
          <Icon name="arrow-round-up" />
        </Fab>
      );
    };
    
    export default FloatingButton;
    

    Now the problem: Where should I do the onPress() method? Because if I leave it in the parent component, it won't work because it is not directly located in the Fab (in FloatingButton). I would like to do the onPress() logic in Fab, but if I do so, the ScrollView that it needs is not available, because it's in the parent component. My idea was to maybe passing the ref as prop into FloatingButton, but for some reason this didn't work.

    Can someone please help me?

  • RuntimeError
    RuntimeError over 4 years
    first of all, thanks a lot for your help. Your code works in my application. However, so far I used Functional Components and would like to stick with them. You used Class components in your example. Is it possible to do it in Functional components, too?
  • RuntimeError
    RuntimeError over 4 years
    You're a genius! Works like a charm.
  • Nicolas Silva
    Nicolas Silva about 3 years
    after over a 100 solutions, this is the only one that actually worked
  • sarfrazanwar
    sarfrazanwar almost 3 years
    spent so much time on this because auto complete was not showing anything like scrollTo. Worked in first try