如何在 React Navigation 中使用嵌套导航器输入 useNavigation?

问题描述 投票:0回答:1

我的裸机 React Native 应用程序中有一个带有 @react-navigation/native v6 的三重嵌套堆栈导航器。

尽管进行了多次尝试,我还是未能正确键入 useNavigation 挂钩。它很实用,但我无法摆脱打字稿的抱怨。

具有全局命名空间定义的RootNavigator:

export type RootStackParamList = {
  ModalNavigator: NavigatorScreenParams<ModalStackParamList>;
};

declare global {
  namespace ReactNavigation {
    interface RootParamList extends RootStackParamList {}
  }
}

const Stack = createStackNavigator<RootStackParamList>();

export const RootNavigator = () => {
  return (
    <Stack.Navigator initialRouteName="ModalNavigator">
      <Stack.Screen name="ModalNavigator" component={ModalNavigator} />
    </Stack.Navigator>
  );
};

模态导航器:

export type ModalStackParamList = {
  ChildStackA: NavigatorScreenParams<ChildStackAParamList>;
  ChildStackB: NavigatorScreenParams<ChildStackBParamList>;
};

const Stack = createStackNavigator<ModalStackParamList>();

export const ModalNavigator = () => {
  return (
    <Stack.Navigator initialRouteName="ChildStackA">
      <Stack.Screen name="ChildStackA" component={ChildNavigatorA} />
      <Stack.Screen name="ChildStackB" component={ChildNavigatorB} />
    </Stack.Navigator>
  );
};

儿童导航器A:

export type ChildStackAParamList = {
  ScreenA: undefined;
  ScreenB: undefined;
};

const StackA = createStackNavigator<ChildStackAParamList>();

export const ChildNavigatorA = () => {
  return (
    <StackA.Navigator initialRouteName="ScreenA">
      <StackA.Screen name="ScreenA" component={ScreenA} />
      <StackA.Screen name="ScreenB" component={ScreenB} />
    </StackA.Navigator>
  );
};

在我的 ScreenA 中,我想要一个使用 useNavigation() 导航到 ScreenB 的组件,如下所示:

type ScreenAProps = CompositeScreenProps<
  StackScreenProps<ChildStackAParamList, 'ScreenA'>,
  CompositeScreenProps<
    StackScreenProps<ModalStackParamList>,
    StackScreenProps<RootStackParamList>
  >
>;

export const ScreenA = ({navigation}: ScreenAProps) => {
  return (
    <View style={styles.view}>
      <Text style={styles.text}>Screen A</Text>
      <NavigateButton />
    </View>
  );
};

const NavigateButton = () => {
  const {navigate} = useNavigation();
  return <Button title="To ScreenB" onPress={() => navigate('ScreenB')} />;
};

虽然代码本身是功能性的,但我收到了这样的打字稿投诉:

No overload matches this call. Argument of type '[string]' is not assignable to parameter of type 'never'. Overload 2 of 2, '(options: never): void', gave the following error. Argument of type 'string' is not assignable to parameter of type 'never'.

如何正确解决这个问题?

重要提示:

  • 根据文档的建议,我不想像这样直接输入
    useNavigation
    useNavigation<SomeNavigationProp>()
  • 我特别想使用 useNavigation,而不是本例中的导航屏幕道具
  • 我不想做类似的事情
    as any
  • 如果可以的话,我可以直接打电话给
    navigate('ScreenB')
    ,而不是
    navigate('ChildStackA', {screen: 'ScreenB'})
    。这在 v5 中有效,没有抱怨。
typescript react-native react-navigation react-navigation-stack
1个回答
0
投票

在 React Navigation v6 中,导航函数需要屏幕名称作为第一个参数,而不仅仅是任何字符串。由于 TypeScript 无法动态推断可能的屏幕名称,因此您需要提供类型提示,让 TypeScript 知道可能的屏幕名称是什么。

您可以通过定义一个表示导航堆栈可能的屏幕名称的类型来实现此目的,然后使用该类型来注释导航功能。

`

import { useNavigation } from '@react-navigation/native';

// Define a type for the possible screen names
type ChildStackANavigationProp = {
  navigate: (screen: 'ScreenA' | 'ScreenB') => void;
};

const NavigateButton = () => {
  const { navigate } = useNavigation<ChildStackANavigationProp>();

  return <Button title="To ScreenB" onPress={() => navigate('ScreenB')} />;
};

`

© www.soinside.com 2019 - 2024. All rights reserved.