Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

useScrollToTop and Scrollables question. #6712

Closed
immortalx opened this issue Sep 27, 2019 · 20 comments
Closed

useScrollToTop and Scrollables question. #6712

immortalx opened this issue Sep 27, 2019 · 20 comments

Comments

@immortalx
Copy link

I'm trying this new version and i'm a little confused about useScrollToTop and the old wrapped FlatList/Scrollview components.

If i got it right, we won't import FlatList/ScrollView from the navigation anymore and to wire useScrollToTop, we just need to add it to the initialScreen of the Stack and the TabBar will listen and fire a scroll to top. Is that correct?

I tried this way and it didn't work, my screen is inside a Stack and I'm using a TabNavigator, i also got a warning about the ref on my screen: "function components cannot be given refs".

Am i missing something here?
Thank you!

@satya164
Copy link
Member

satya164 commented Oct 3, 2019

Can you give an example of what you're trying to do?

@immortalx
Copy link
Author

@satya164 In v4.0 i just need to import FlatList from react-navigation and when i double click on a bottom tab icon it scrolls to the top. I'm trying to understand how to do that in this new version since it doesn't export it anymore.

@satya164
Copy link
Member

satya164 commented Oct 3, 2019

export default function MyScreen() {
  const ref = React.useRef<ScrollView>(null);

  useScrollToTop(ref);

  return (
    <ScrollView ref={ref}>
      {/* ... */}
    </ScrollView>
  );
}

@satya164 satya164 closed this as completed Oct 3, 2019
@immortalx
Copy link
Author

@satya164 That was my first try, got this error :
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

@satya164
Copy link
Member

satya164 commented Oct 4, 2019

@immortalx can't say without the code. but sounds like you're not passing the ref to a ScrollView/FlatList, but to something else.

@immortalx
Copy link
Author

@satya164 Here's my code, i tried with ScrollView too. I will try to reproduce on a new project. The ref error was related to a different code, i fixed that but still, double click on the bottom bar doesn't scroll to top.
Thanks for the help!

export default function FeedScreen({ route, navigation }) {
  const ref = React.useRef<FlatList>(null)
  useScrollToTop(ref)

  return (
    <View style={{ flex: 1 }}>
      <FlatList
        ref={ref}
       {/* ... */}
     />
    </View>
  )
}

const FeedStack = createStackNavigator()
const FeedStackScreen = () => (
  <FeedStack.Navigator>
    <FeedStack.Screen name="FeedScreen" component={FeedScreen} />
  </FeedStack.Navigator>
)
const Tab = createBottomTabNavigator()

export default () => {
  return (
    <NavigationNativeContainer>
      <Tab.Navigator
        initialRouteName="FeedStackScreen"
        lazy={false}
        tabBarOptions={{
          activeTintColor: colors.blue,
          showLabel: false
        }}>
        <Tab.Screen
          name="FeedStackScreen"
          component={FeedStackScreen}
          options={{
            tabBarIcon: ({ tintColor }) => (
              <FontAwesome5 name="home" color={tintColor} size={NAVICON_SIZE} />
            )
          }}
        />
      </Tab.Navigator>
    </NavigationNativeContainer>
  )
}

@immortalx
Copy link
Author

@satya164 Tested with an empty project react-native 0.61.2. Seems like the issue happens when i have a stack navigator for each tab.

Also it only works with React.createRef(), useRef gives me an error: "Unhandled JS Exception: Invariant Violation: Function components cannot have refs. Did you mean to use React.forwardRef()?"

Just tried the examples from https://reactnavigation.org/docs/en/next/tab-based-navigation.html

"Minimal example of tab-based navigation" works.

"A stack navigator for each tab" doesn't work.

import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationNativeContainer, useScrollToTop } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import * as React from 'react';
import { Button, ScrollView, Text, View } from 'react-native';


function DetailsScreen() {
  const ref = React.createRef()

  useScrollToTop(ref)

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <ScrollView ref={ref}>
        {/*...*/}   
      </ScrollView>
    </View>
  );
}

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      {/* other code from before here */}
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

function SettingsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      {/* other code from before here */}
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

const HomeStack = createStackNavigator();

function HomeStackScreen() {
  return (
    <HomeStack.Navigator>
      <HomeStack.Screen name="Home" component={DetailsScreen} />
      <HomeStack.Screen name="Details" component={HomeScreen} />
    </HomeStack.Navigator>
  );
}

const SettingsStack = createStackNavigator();

function SettingsStackScreen() {
  return (
    <SettingsStack.Navigator>
      <SettingsStack.Screen name="Settings" component={SettingsScreen} />
      <SettingsStack.Screen name="Details" component={DetailsScreen} />
    </SettingsStack.Navigator>
  );
}

const Tab = createBottomTabNavigator();

export default function App() {
  return (
    <NavigationNativeContainer>
      <Tab.Navigator>
        <Tab.Screen name="Home" component={HomeStackScreen} />
        <Tab.Screen name="Settings" component={SettingsStackScreen} />
      </Tab.Navigator>
    </NavigationNativeContainer>
  );
}

@satya164
Copy link
Member

satya164 commented Oct 4, 2019

Also it only works with React.createRef()

It creates a new ref every render. useRef is the correct function to use here.

"Unhandled JS Exception: Invariant Violation: Function components cannot have refs. Did you mean to use React.forwardRef()?"

Can you share some code where it happens on snack.expo.io?

"A stack navigator for each tab" doesn't work

It doesn't work inside nested navigators.

@immortalx
Copy link
Author

The ref error is related to typescript i will need to investigate it more.
Thank you!

@nhuesmann
Copy link

It doesn't work inside nested navigators.

Hey @satya164, what do you mean by "It doesn't work inside nested navigators"? Does that mean that useScrollToTop will not work in a stack navigator that is inside a tab navigator? If so, how should we go about using it in any tabs? A StackNavigator nested inside a TabNavigator is an extremely common use case.

@lucasmotta
Copy link

Hey @satya164, is it worth creating a separated issue to handle this problem of nested navigators inside a TabNavigator? Or should we reopen this?

I agree with @nhuesmann that this is a very common pattern.

@satya164
Copy link
Member

satya164 commented Nov 4, 2019

Please upgrade to the lastest version. It works with nested navigators.

@immortalx
Copy link
Author

Thank you!

@nhuesmann
Copy link

Can confirm it's working in latest version. Thank you @satya164!

@satya164 satya164 transferred this issue from react-navigation/navigation-ex Feb 7, 2020
@petera2c
Copy link

petera2c commented May 7, 2021

It does not work in the latest version with nested navigations

@KresimirJurkovic
Copy link

Yep, same here, cannot get it to work

@github-actions
Copy link

Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.

@DomVinyard
Copy link

I would also love for it to work with nested navigations

@julien-moha
Copy link

Since nested navigators is actually a very common thing, it would be nice if it could work with. Has anyone found a trick?

@basememara
Copy link

basememara commented Jan 29, 2024

useScrollToTop still isn't working with nested navigators as of v6.1.9. You can clone a simple example here.

It seems to scroll to the top of the nearest header even tho that header has headerShown: false, or I think it might not be considering the safe areas.

Simulator Screen Recording - iPhone 15 Pro - 2024-01-29 at 16 54 42

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants