Having a navigation type definition as bellow, when I navigate from e.g AOne
to BTwo
with id:99
the console log of props.route.params
shows correct info. But props.route.params.id
throws type error
TypeError: undefined is not an object (evaluating 'props.route.params.id')
// navigation related imports in all components
import {BottomTabScreenProps} from '@react-navigation/bottom-tabs';
import {CompositeScreenProps, NavigatorScreenParams} from '@react-navigation/core';
import {StackScreenProps} from '@react-navigation/stack';
// type defenitions
export type StackOneParams = {
AOne:undefined,
BOne: undefined,
// some other screens
};
export type StackTwoParams = {
ATwo: undefined;
BTwo:{id:number};
// some other screens
};
export type TabParams = {
StackOne: NavigatorScreenParams<StackOneParams>;
StackTwo: NavigatorScreenParams<StackTwoParams>;
// ... some other stacks each represent a tab
};
export type RootParamList = {
ROne: undefined; // these screens should stand alone and not blong to any tab
RTwo: undefined;
Tabs: NavigatorScreenParams<TabParams>
}
// navigation from AOne to BTwo
props.navigation.navigate('Tabs', {
screen: 'StackTwo',
params: {screen: 'BTwo', params: {id: 99}}
}); // this part give correct auto complete hints in VSCode and no compilation error
// BTwo component (screen)
//--------------------------------
type Props = CompositeScreenProps<
StackScreenProps<RootParamList, 'Tabs'>,
CompositeScreenProps<
BottomTabScreenProps<TabPrams, 'StackTwo'>,
StackScreenProps<StackTwoParams, 'BTwo'>
>
>;// using CompositeScreenProps to be able to navigate to screens in another tabs
// otherwise just `type Props=StackScreenProps<StackTwoParams, 'BTwo'>` works fine but cannot navigate to other tabs
const BTwo:React.FC<Props> = (props) =>{
console.log(props.route.params)// the log shows {id:23}
// but props.route.params.id gives error and also no auto completion hint
return(...)
}
most of the examples (and the official documentation) show the most simple composition where the target screen is not even in second level of nesting (in the official doc profile
is not really in nested bottom tabs)
How should I solve the type error in this case?
the image shows the VSCode auto-complete suggestions
My other explanations were not quite accurate. The way you have defined the CompositeScreenProp
is not correct. Here is the correct way to implement this.
type ScreenProps = CompositeScreenProps<
StackScreenProps<StackTwoParams, "BTwo">,
CompositeScreenProps<
BottomTabScreenProps<TabParams, "StackTwo">,
StackScreenProps<RootParamList>
>
>
The first parameter of CompositeScreenProps
contains the type of the navigator that owns the screen. In this case BTwo
is owned by StackTwo
and this determines the primary navigator, which is a Stack
.
The above yields to the correct types as well.
const BTwo = (props: ScreenProps) => {
return <></>
}
We can type the navigation object and the route object separately as follows.
type NavigationProps = CompositeNavigationProp<
StackNavigationProp<StackTwoParams, "BTwo">,
CompositeNavigationProp<
BottomTabNavigationProp<TabParams, "StackTwo">,
StackNavigationProp<RootParamList>
>
>
type ScreenPropsA = {
navigation: NavigationProps
route: RouteProp<StackTwoParams, "BTwo">
}
Notice the usage of CompositeNavigationProp
and RouteProp
here.
Then, use it as follows.
const BTwo = ({ route, navigation }: ScreenProps) => {
return <></>
}
Both, route
and navigation
are now correctly typed.