React Navigation 5 ошибка типа при навигации между стеками - PullRequest
0 голосов
/ 09 февраля 2020

Я получаю некоторые ошибки TypeScript при использовании реакции-навигации 5. Я уверен, что это то, что я делаю неправильно в отношении того, как я пишу вещи или структурирую приложение, но я не уверен, что.

Я следовал этим руководствам по документации в качестве отправной точки:

https://reactnavigation.org/docs/en/tab-based-navigation.html#a -stack-navigator-for-each-tab https://reactnavigation.org/docs/en/typescript.html

Я хочу, чтобы структура приложения была такой:

  • Root Навигатор вкладок
    • Домашний стек
      • Домашняя страница
      • Страница сведений о новостях
    • Стек настроек
      • Страница настроек

Все работает нормально, когда работает, но я получаю некоторые ошибки при попытке перейти со страницы внутри одного стека на страницу другого стека, например, переход с Страница сведений о новостях на Страница настроек .

Это код, который у меня сейчас есть.

import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { createStackNavigator, StackNavigationProp } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import { RouteProp } from '@react-navigation/core';

enum AppRoute {
    // Home Stack
    HOME = 'HOME',
    NEWS_DETAILS = 'NEWS_DETAILS',

    // Settings Stack
    SETTINGS = 'SETTINGS',
}

type HomeStackParamList = {
    [AppRoute.HOME]: undefined;
    [AppRoute.NEWS_DETAILS]: {
        id: number;
    };
}

type SettingsStackParamList = {
    [AppRoute.SETTINGS]: undefined;
}


type HomeProps = {
    navigation: StackNavigationProp<
        HomeStackParamList,
        AppRoute.HOME
    >;
    route: RouteProp<HomeStackParamList, AppRoute.HOME>;
}

type NewsDetailsProps = {
    navigation: StackNavigationProp<
        HomeStackParamList,
        AppRoute.NEWS_DETAILS
    >;
    route: RouteProp<HomeStackParamList, AppRoute.NEWS_DETAILS>;
}

type SettingsProps = {
    navigation: StackNavigationProp<
        SettingsStackParamList,
        AppRoute.SETTINGS
    >;
    route: RouteProp<SettingsStackParamList, AppRoute.SETTINGS>;
}


// ----------------------------------------------------------------------------

function HomeScreen(props: HomeProps) {
    const { navigation } = props;

    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Home screen</Text>
            <Button
                title="Go to Details"
                onPress={() => navigation.navigate(AppRoute.NEWS_DETAILS, { id: 1 })}
            />
            <Button
                title="Go to Settings"
                onPress={() => navigation.navigate(AppRoute.SETTINGS)}
            />
        </View>
    );
}


function DetailsScreen(props: NewsDetailsProps) {
    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Details! {props.route.params.id}</Text>
        </View>
    );
}


function SettingsScreen(props: SettingsProps) {
    const { navigation } = props;

    return (
        <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
            <Text>Settings screen</Text>
            <Button
                title="Go to Home -> Details"
                onPress={() => navigation.navigate(AppRoute.NEWS_DETAILS, { id: 2 })}
            />
        </View>
    );
}

const HomeStack = createStackNavigator<HomeStackParamList>();

function HomeStackScreen() {
    return (
        <HomeStack.Navigator>
            <HomeStack.Screen name={AppRoute.HOME} component={HomeScreen} />
            <HomeStack.Screen name={AppRoute.NEWS_DETAILS} component={DetailsScreen} />
        </HomeStack.Navigator>
    );
}


const SettingsStack = createStackNavigator<SettingsStackParamList>();

function SettingsStackScreen() {
    return (
        <SettingsStack.Navigator>
            <SettingsStack.Screen name={AppRoute.SETTINGS} component={SettingsScreen} />
        </SettingsStack.Navigator>
    );
}


const Tab = createBottomTabNavigator();

type TabNavigatorProps = React.ComponentProps<typeof Tab.Navigator>;

export const AppNavigator = (props: Partial<TabNavigatorProps>): React.ReactElement => {
    return (
        <Tab.Navigator>
            <Tab.Screen name="Home" component={HomeStackScreen} />
            <Tab.Screen name="Settings" component={SettingsStackScreen} />
        </Tab.Navigator>
    );
}

Я получаю эту ошибку:

No overload matches this call.
  Argument of type '[AppRoute.SETTINGS]' is not assignable to parameter of type '[AppRoute.HOME | AppRoute.NEWS_DETAILS] | [AppRoute.HOME | AppRoute.NEWS_DETAILS, { id: number; }]'.
    Type '[AppRoute.SETTINGS]' is not assignable to type '[AppRoute.HOME | AppRoute.NEWS_DETAILS]'.
      Type 'AppRoute.SETTINGS' is not assignable to type 'AppRoute.HOME | AppRoute.NEWS_DETAILS'.
  Overload 2 of 2, '(route: { key: string; params?: { id: number; }; } | { name: AppRoute.HOME | AppRoute.NEWS_DETAILS; key?: string; params: { id: number; }; }): void', gave the following error.
    Argument of type 'AppRoute.SETTINGS' is not assignable to parameter of type '{ key: string; params?: { id: number; }; } | { name: AppRoute.HOME | AppRoute.NEWS_DETAILS; key?: string; params: { id: number; }; }'.ts(2769)

I thi Я понимаю, почему это происходит, потому что HomeStackParamList не имеет заданного маршрута настроек. Должен ли я создать тип объединения для всех параметров страницы стеков и использовать его везде, чтобы у меня не было этой ошибки, или есть лучший способ структурировать это?

Я думаю, что мог бы просто создать объединение Тип всех списков параметров, как это, но я не уверен, что это правильный путь или нет? Примерно так:

type HomeStackParamList = {
    [AppRoute.HOME]: undefined;
    [AppRoute.HOME_DETAILS]: {
        id: number;
    };
}

type SettingsStackParamList = {
    [AppRoute.SETTINGS]: undefined;
}

type AppStackParamList = HomeStackParamList & SettingsStackParamList;

type HomeProps = {
    navigation: StackNavigationProp<
        AppStackParamList,
        AppRoute.HOME
    >;
    route: RouteProp<AppStackParamList, AppRoute.HOME>;
}

type DetailsProps = {
    navigation: StackNavigationProp<
        AppStackParamList,
        AppRoute.HOME_DETAILS
    >;
    route: RouteProp<AppStackParamList, AppRoute.HOME_DETAILS>;
}

type SettingsProps = {
    navigation: StackNavigationProp<
        AppStackParamList,
        AppRoute.SETTINGS
    >;
    route: RouteProp<AppStackParamList, AppRoute.SETTINGS>;
}

Буду очень признателен за любую помощь, чтобы указать мне правильное направление, спасибо

1 Ответ

0 голосов
/ 10 февраля 2020

Да, объединение списков параметров подходит для этого варианта использования.

...