React Native底部选项卡导航器元素不可赋值

p5cysglq  于 2023-05-18  发布在  React
关注(0)|答案(2)|浏览(138)

我是React和TypeScript的新手,我用Expo Go创建了一个包含React Bottom Tab Navigator(https://reactnavigation.org/docs/bottom-tab-navigator/)的应用程序。我的问题是这个例子没有定义{navigation}参数的类型,我想解决这个问题。
注意:它的工作没有定义的类型,但我想学习和了解如何修复它。
我有一个Navigation.tsx,包含我的根堆栈和选项卡(我希望我将它限制在相关部分)

const Stack = createNativeStackNavigator();
   
declare global {
    namespace ReactNavigation {
        interface RootParamList extends RootStackParamList { }
    }
}
    
type RootStackParamList = {
    Tabs: NavigatorScreenParams<RootTabParamList> | undefined;
    Modal: undefined;
    NotFound: undefined;
};

export type RootStackScreenProps<Screen extends keyof RootStackParamList> = NativeStackScreenProps<
    RootStackParamList,
    Screen
>;
    
const BottomTab = createBottomTabNavigator<RootTabParamList>();
    
type RootTabParamList = {
    About: undefined;
    Test: undefined;
};
    
export type RootTabScreenProps<Screen extends keyof RootTabParamList> = CompositeScreenProps<
    BottomTabScreenProps<RootTabParamList, Screen>,
    NativeStackScreenProps<RootStackParamList>
>;
   
export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) {
    return (
        <NavigationContainer
            linking={LinkingConfiguration}
            theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}
        >
            <Stack.Navigator>
                <Stack.Screen name="Tabs" component={BottomTabNavigator} options={{ headerShown: false }}/>
                // (!) Problem line
                <Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }}/>
                <Stack.Group screenOptions={{ presentation: 'modal' }}>
                    <Stack.Screen name="Modal" component={ModalScreen} />
                </Stack.Group>
            </Stack.Navigator>
        </NavigationContainer>
    );
}

我在其中一个选项卡中找到了{navigation}的正确类型,eidogg。About.tsx

import React from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';

import { Text, View } from '../ui/Components';
import { RootTabScreenProps } from '../ui/Navigation';

export default function About({ navigation }: RootTabScreenProps<'About'>) {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>About</Text>
      <View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
      <Text>/screens/About.tsx</Text>
      <TouchableOpacity onPress={() => navigation.replace('Tabs')}>
        <Text>Go to home screen!</Text>
      </TouchableOpacity>
    </View>
  );
}

但是我在根组件中找不到{navigation}的正确类型(没有选项卡),比如NotFound.tsx

import React from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';

import { Text, View } from '../ui/Components';

// (!) Problem line
export default function NotFoundScreen({ navigation }: ?????) {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>This screen doesn't exist.</Text>
      <TouchableOpacity onPress={() => navigation.replace('Tabs')} style={styles.link}>
        <Text style={styles.linkText}>Go to home screen!</Text>
      </TouchableOpacity>
    </View>
  );
}

如果没有类型,我(当然)在NotFound.tsx中得到一个错误,即
绑定元素“navigation”隐式具有“any”类型。
我尝试了RootStackScreenProps<'NotFound'>,这会让上面的错误消失,但是我在Navigation.tsx<Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }}/>中得到一个错误:
键入'({ navigation }:RootStackScreenProps<“NotFound”>)=> Element'不能赋值给类型'ScreenComponentType<ParamListBase,“NotFound”>|未定义'。
键入'({ navigation }:RootStackScreenProps<“NotFound”>)=> Element'不可分配给类型'FunctionComponent<{}>'。
参数“__0”和“props”的类型不兼容。
类型“{}”缺少类型“RootStackScreenProps<“NotFound”>”中的以下属性:导航,路线
那么……什么是正确的类型在这里使用?

nzk0hqpo

nzk0hqpo1#

react navigation是用typescript编写的,所以你需要的任何类型都可能存在。在这里,他们介绍了如何键入堆栈导航器,以及底部选项卡导航器的相同前提。你只需要在你的NotFound.tsx中导出RootStackParamList并导入NativeStackScreenProps

import React from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';
import { RootStackParamList } from '../ui/Navigation';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { Text, View } from '../ui/Components';

type Props = NativeStackScreenProps<RootStackParamList>; // don't use <Screen> here

export default function NotFoundScreen({ navigation }: Props) {
  return (
    <View style={styles.container}>
      <Text style={styles.title}>This screen doesn't exist.</Text>
      <TouchableOpacity onPress={() => navigation.replace('Tabs')} style={styles.link}>
        <Text style={styles.linkText}>Go to home screen!</Text>
      </TouchableOpacity>
    </View>
  );
}
dxxyhpgq

dxxyhpgq2#

感谢@phantomspooks的帮助和他的答案(https://stackoverflow.com/a/76248413/4090157),我想我现在对类型的理解更好了一点。
我终于能够通过以下更改解决我的问题:
1.从Navigation.tsx中的export type RootStackScreenProps中删除<Screen>

export type RootStackScreenProps = NativeStackScreenProps<
    RootStackParamList
>;

1.在NotFound.tsx中使用该类型

export default function NotFoundScreen({ navigation }: RootStackScreenProps) {
    ...
}

相关问题