React Native Scrollview: scroll to top on button click

Viewed 13074

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?

3 Answers

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>
    );
}

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 });
}

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

https://snack.expo.io/@anurodhs2/restless-edamame
Related