使用 Typescript [react-navigation v6] 在嵌套导航器中获取路由参数时出现类型错误
Type error in getting route params within nested navigator using Typescript [react-navigation v6]
-
react-native
-
react-navigation
-
react-navigation-stack
-
react-navigation-bottom-tab
-
react-navigation-v6
具有如下导航类型定义,当我使用 id:99
从 AOne
导航到 BTwo
时,props.route.params
的控制台日志显示正确的信息。但是 props.route.params.id
抛出类型错误
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(...)
}
- 这是为特定屏幕定义屏幕道具的正确方法吗,就像我在 BTwo 屏幕中使用的那样?还是作文顺序不一样?
大多数示例 (and the official documentation) 显示了最简单的构图,其中目标屏幕甚至不在第二层嵌套中(在官方文档中 profile
并不真正在嵌套底部选项卡中)
这种情况下应该如何解决类型错误?
图像显示 VSCode 自动完成建议
使用 CompositeScreenProps 的解决方案
我的其他解释不太准确。您定义 CompositeScreenProp
的方式不正确。这是实现它的正确方法。
type ScreenProps = CompositeScreenProps<
StackScreenProps<StackTwoParams, "BTwo">,
CompositeScreenProps<
BottomTabScreenProps<TabParams, "StackTwo">,
StackScreenProps<RootParamList>
>
>
CompositeScreenProps
的第一个参数包含 拥有屏幕 的导航器的类型。在这种情况下,BTwo
归 StackTwo
所有,这决定了主导航器,即 Stack
.
以上也产生了正确的类型。
const BTwo = (props: ScreenProps) => {
return <></>
}
导航和路线使用不同类型的解决方案
我们可以分别输入导航对象和路由对象,如下所示。
type NavigationProps = CompositeNavigationProp<
StackNavigationProp<StackTwoParams, "BTwo">,
CompositeNavigationProp<
BottomTabNavigationProp<TabParams, "StackTwo">,
StackNavigationProp<RootParamList>
>
>
type ScreenPropsA = {
navigation: NavigationProps
route: RouteProp<StackTwoParams, "BTwo">
}
注意这里 CompositeNavigationProp
和 RouteProp
的用法。
然后,如下使用。
const BTwo = ({ route, navigation }: ScreenProps) => {
return <></>
}
route
和 navigation
现在都可以正确输入。
react-native
react-navigation
react-navigation-stack
react-navigation-bottom-tab
react-navigation-v6
具有如下导航类型定义,当我使用 id:99
从 AOne
导航到 BTwo
时,props.route.params
的控制台日志显示正确的信息。但是 props.route.params.id
抛出类型错误
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(...)
}
- 这是为特定屏幕定义屏幕道具的正确方法吗,就像我在 BTwo 屏幕中使用的那样?还是作文顺序不一样?
大多数示例 (and the official documentation) 显示了最简单的构图,其中目标屏幕甚至不在第二层嵌套中(在官方文档中 profile
并不真正在嵌套底部选项卡中)
这种情况下应该如何解决类型错误?
图像显示 VSCode 自动完成建议
使用 CompositeScreenProps 的解决方案
我的其他解释不太准确。您定义 CompositeScreenProp
的方式不正确。这是实现它的正确方法。
type ScreenProps = CompositeScreenProps<
StackScreenProps<StackTwoParams, "BTwo">,
CompositeScreenProps<
BottomTabScreenProps<TabParams, "StackTwo">,
StackScreenProps<RootParamList>
>
>
CompositeScreenProps
的第一个参数包含 拥有屏幕 的导航器的类型。在这种情况下,BTwo
归 StackTwo
所有,这决定了主导航器,即 Stack
.
以上也产生了正确的类型。
const BTwo = (props: ScreenProps) => {
return <></>
}
导航和路线使用不同类型的解决方案
我们可以分别输入导航对象和路由对象,如下所示。
type NavigationProps = CompositeNavigationProp<
StackNavigationProp<StackTwoParams, "BTwo">,
CompositeNavigationProp<
BottomTabNavigationProp<TabParams, "StackTwo">,
StackNavigationProp<RootParamList>
>
>
type ScreenPropsA = {
navigation: NavigationProps
route: RouteProp<StackTwoParams, "BTwo">
}
注意这里 CompositeNavigationProp
和 RouteProp
的用法。
然后,如下使用。
const BTwo = ({ route, navigation }: ScreenProps) => {
return <></>
}
route
和 navigation
现在都可以正确输入。