Reset ScrollView to the top after render (react-navigation v4)

Viewed 533

How can I reset the ScrollView to the top of it each time I navigate to the screen where said ScrollView is located? (I'm using react-navigation v4).

I've seen a post where the solution implies the use of:

import { useIsFocused } from "@react-navigation/native";

and then use a hook:

const isFocused = useIsFocused();
useEffect(() => {
    if (isFocused) {
        scrollViewRef.current?.scrollTo(0, 0, true);
    }
}, [isFocused]);

However, since I'm using v4, that option is not available for my project. What can I do?

2 Answers

With react-navigation v4 an, here is how you can scroll the ScrollView to the top on screen focus:

import React, {useEffect} from 'react';
import {View, Button, ScrollView} from 'react-native';

export default function Screen1({navigation}) {
  const scrollViewRef = React.createRef();
  useEffect(() => {
    const focusListener = navigation.addListener('didFocus', () => {
      scrollViewRef?.current?.scrollTo({x: 0, y: 0, animated: true});
    });

    return () => focusListener.remove();
  }, [navigation, scrollViewRef]);

  return (
    <View>
      <Button
        title={'Go to screen 2'}
        onPress={() => navigation.navigate('screen2')}
      />
      <ScrollView ref={scrollViewRef}>
        <View
          style={{
            height: 300,
            borderWidth: 1,
            marginHorizontal: 15,
            marginTop: 10,
          }}
        />
        <View
          style={{
            height: 600,
            borderWidth: 1,
            marginHorizontal: 15,
            marginTop: 10,
          }}
        />
        <View
          style={{
            height: 200,
            borderWidth: 1,
            marginHorizontal: 15,
            marginTop: 10,
          }}
        />
      </ScrollView>
    </View>
  );
}

The basic idea is:

  • Create a ref and assign it to the ScrollView
  • Add didFocus listener provided by the react-navigation
  • Use scrollViewRef?.current?.scrollTo({x: 0, y: 0, animated: true}); to scroll the ScrollView to the top

An easy solution to your problem is to use React Ref hook, just pass the ref of your scrollable component to their useScrollToTop hook.

import * as React from 'react'
import { ScrollView } from 'react-native'
import { useIsFocused } from "@react-navigation/native"



function demo() {
  const ref = React.useRef(null)

  useIsFocused(ref)

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

References:

Snack.expo.io Example

React Navigation Documentation

Related