You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Navigation嵌套导航器中useNavigation的类型定义方案

解决React Navigation v6三层嵌套栈中useNavigation的TypeScript类型问题

问题根源

子组件NavigateButton中的useNavigation默认获取的是顶层RootStack导航的类型,而顶层路由列表中不存在ScreenB,因此TypeScript报错。我们需要让useNavigation自动推断当前所在的ChildStackA栈的导航类型。


解决方案(满足所有要求)

方案1:简化ScreenA的Props类型(无需访问父级导航时使用)

如果ScreenA不需要跳转至父级栈(比如ChildStackB),直接使用当前栈的StackScreenProps即可让useNavigation自动推断类型:

// ScreenA.tsx
import type { StackScreenProps } from '@react-navigation/stack';
import type { ChildStackAParamList } from './ChildNavigatorA';

// 仅保留当前栈的屏幕Props类型
type ScreenAProps = StackScreenProps<ChildStackAParamList, 'ScreenA'>;

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

const NavigateButton = () => {
  const { navigate } = useNavigation();
  // 此时TypeScript可正确推断'ScreenB'为合法路由
  return <Button title="To ScreenB" onPress={() => navigate('ScreenB')} />;
};

方案2:保留父级导航访问(使用CompositeScreenProps时)

如果需要在ScreenA中同时操作当前栈和父级栈,可封装自定义导航钩子避免直接给useNavigation加泛型:

  1. 创建自定义钩子文件:
// hooks/useChildStackANavigation.ts
import { useNavigation } from '@react-navigation/native';
import type { StackNavigationProp } from '@react-navigation/stack';
import type { ChildStackAParamList } from '../ChildNavigatorA';

// 内部封装泛型,对外暴露无泛型的钩子
export const useChildStackANavigation = () => 
  useNavigation<StackNavigationProp<ChildStackAParamList>>();
  1. 在ScreenA的子组件中使用该钩子:
// ScreenA.tsx
import { useChildStackANavigation } from './hooks/useChildStackANavigation';

// 保留原CompositeScreenProps以支持父级导航操作
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 } = useChildStackANavigation();
  return <Button title="To ScreenB" onPress={() => navigate('ScreenB')} />;
};

验证全局命名空间定义

确保全局路由类型定义正确,无需修改:

// RootNavigator.tsx
export type RootStackParamList = {
  ModalNavigator: NavigatorScreenParams<ModalStackParamList>;
};

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

内容的提问来源于stack exchange,提问作者MissingSemicolon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:23:11