How to access NavigatorScreen > options inside Screen component?
Asked Answered
G

2

6

Is there any way I could access navigator-screen options object inside Home component ?

    <Stack.Navigator>
        <Stack.Screen
            name="Home"
            component={Home}
            options={
                {
                    /** some options... */
                }
            }
        />
        <Stack.Screen name="About" component={About} />
    </Stack.Navigator>

Home

function Home() {
    /** Get options object here */
    return (
        /** some jsx */
    );
}

I'm using react-navigation 5

Gyp answered 5/6, 2021 at 9:11 Comment(0)
S
1

The only way I found was to keep a ref of your NavigationContainer, and then use containerRef.getCurrentOptions().

Presumably global refs are an anti-pattern, but there didn't seem to be a way to get options from a hook. I could only find navigation.setOptions(), but nothing about getOptions().

This is how I did it:

const navigation = useNavigation();
  useEffect(() => {
    // Can't use the useNavigation or useNavigationContainerRef hooks here as they return undefined in options
    const unsubscribe = RootNavigation.navigationRef.current?.addListener('options', event => {
      // Get the screen options for the currently focused screen
      const options: NativeStackNavigationOptions | BottomTabNavigationOptions = event.data.options;
      // Only take the headerTitle if it's a string, otherwise take the title
      const screenTitle =
        typeof options?.headerTitle === 'string' ? options?.headerTitle : options?.title;
      setTitle(screenTitle);
    });
    const options: NativeStackNavigationOptions | BottomTabNavigationOptions | undefined =
      RootNavigation.navigationRef.current?.getCurrentOptions();
    const screenTitle =
      typeof options?.headerTitle === 'string' ? options?.headerTitle : options?.title;
    setTitle(screenTitle);

    return () => {
      unsubscribe?.();
    };
  }, [navigation]);

I used this code to create a custom screen title for all screens, that can scroll with the screen content.

It may look redundant fetching options for twice, however I found either approach alone, somehow, wasn't 100% reliable. I kept getting undefined in some screens if I don't run the same logic for twice in two blocks.

The navigation options isn't available immediately when the screen renders, and only appeares to have a value some time later on.

addListener('options') worked better when navigating inside the same navigator, whereas the other block of code helps when jumping between navigators.

Shutdown answered 19/2 at 4:49 Comment(0)
M
-5

you can use navigation.setOptions for your home screen

function Home({ navigation, route }) {
  React.useLayoutEffect(() => {
    navigation.setOptions({ headerTitle: getHeaderTitle(route) });
  }, [navigation, route]);
}

for more detals you can read this documentation screen options

Melancholia answered 5/6, 2021 at 11:54 Comment(1)
Thank you for your answer ... but I have no issue with setting options ... The issue is how to retrieve these options inside HomeGyp

© 2022 - 2024 — McMap. All rights reserved.