Навигация не определена в содержимом ящика

#typescript #react-native #react-navigation

#typescript #react-native #реагировать-навигация

Вопрос:

В настоящее время я пытаюсь создать проект React Native с использованием typescript. Мои экраны настроены следующим образом:

 export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) {
    return (
        <NavigationContainer linking={LinkingConfiguration} theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
            <DrawerNavigator />
        </NavigationContainer>
    );
}

const Drawer = createDrawerNavigator<DrawerStackParamList>();

function DrawerNavigator() {
    const navigation = useNavigation<NavigationProps>();
    return (
        <Drawer.Navigator drawerContent={() => <DrawerContent navigation={navigation} />}>
            <Drawer.Screen name='Root' component={RootNavigator} />
            <Drawer.Screen name='ManageCities' component={ManageCities} />
        </Drawer.Navigator>
    );
}

const Stack = createStackNavigator<RootStackParamList>();

function RootNavigator() {
    return (
        <Stack.Navigator>
            <Stack.Screen name='Root' component={BottomTabNavigator} options={{ headerShown: true, headerLeft: () => <Header /> }} />
            <Stack.Screen name='NotFound' component={NotFoundScreen} options={{ title: 'Oops!', headerShown: true, headerLeft: () => <Header /> }} />
        </Stack.Navigator>
    );
}

function Header() {
    const navigation = useNavigation<NavigationProps>();
    return <Ionicons size={30} name='ios-menu' color='white' onPress={() => navigation.toggleDrawer()} />;
}
 

Содержимое ящика:

 import React, { FunctionComponent } from 'react';
import { View } from '../components/Themed';
import { DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';
import { NavigationProps } from '../types';

type DrawerContentProps = {
    navigation?: NavigationProps;
};

const DrawerContent: FunctionComponent<DrawerContentProps> = ({ navigation }) => {
    const arr = ['city1', 'city2'];

    return (
        <View style={{ flex: 1 }}>
            <DrawerContentScrollView>
                {arr.map(
                    (value): JSX.Element => {
                        return <DrawerItem key={value} label={value} onPress={() => console.log(value)} />;
                    },
                )}
                <DrawerItem label='Manage Cities' onPress={() => navigation.navigate('ManageCities')} />
            </DrawerContentScrollView>
        </View>
    );
};

export default DrawerContent;

 

когда я пытаюсь запустить приложение, я получаю следующую ошибку:

 Error: Couldn't find a navigation object. Is your component inside a screen in a navigator?

This error is located at:
    in DrawerNavigator
    in EnsureSingleNavigator (created by ForwardRef(BaseNavigationContainer))
    in ForwardRef(BaseNavigationContainer) (created by ForwardRef(NavigationContainer))
    in ThemeProvider (created by ForwardRef(NavigationContainer))
    in ForwardRef(NavigationContainer) (created by Navigation)
    in Navigation (created by App)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by App)
    in App (created by ExpoRoot)
    in ExpoRoot
    in RCTView (created by View)
    in View (created by AppContainer)
    in DevAppContainer (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
 

Я также пытался использовать useNavigation хук внутри содержимого ящика, но столкнулся с той же ошибкой.

На самом деле моя первоначальная проблема заключалась в том, что я не мог понять, как передать навигацию в качестве опоры DrawerNavigator . При использовании Javascript вы можете передавать реквизиты, и по умолчанию внутри него есть навигация. Однако в Typescript он жалуется, что реквизиты не определены, и я не мог понять, как передать его изначально.

Ответ №1:

Вот мое решение:

 function DrawerNavigator() {
    return (
        <Drawer.Navigator drawerContent={DrawerContent}>
            <Drawer.Screen name='Root' component={RootNavigator} />
            <Drawer.Screen name='ManageCities' component={ManageCities} />
        </Drawer.Navigator>
    );
}
 

Когда я изменил содержимое ящика следующим образом, навигационные реквизиты больше не определены:

 const DrawerContent: FunctionComponent<DrawerContentComponentProps> = ({ navigation }) => {
    const arr = ['city1', 'city2'];

    return (
        <View style={{ flex: 1 }}>
            <DrawerContentScrollView>
                {arr.map(
                    (value): JSX.Element => {
                        return <DrawerItem key={value} label={value} onPress={() => console.log(value)} />;
                    },
                )}
                <DrawerItem label='Manage Cities' onPress={() => navigation.navigate('ManageCities')} />
            </DrawerContentScrollView>
        </View>
    );
 

Ответ №2:

Это работает для меня

 function DrawerScreens() {
    return (
        <DrawersNavigation.Navigator drawerContent={(props) => <DrawerNavigation  {...props} />} screenOptions={navigationOptions}>
            ...
        </DrawersNavigation.Navigator>
    );
}