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.
options
... The issue is how to retrieve these options insideHome
– Gyp