无需导航道具即可导航 - typescript 打字

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

我正在尝试将 React Navigation 6.x 包含到带有 Redux 的 React Native 项目中,因此需要能够从外部组件访问导航器。

我正在遵循本指南(在没有导航道具的情况下导航)并且具有与示例中基本相同的代码,其功能正常:

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

export const navigationRef = createNavigationContainerRef()

export function navigate(name, params) {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
}

但是我也在使用 Typescript。

React Navigation 还有一个关于集成 Typescript 的指南(使用 TypeScript 进行类型检查),其中展示了如何键入导航引用本身,这也很好用:

export const navigationRef = createNavigationContainerRef<RootStackParamList>();

虽然没有输入

navigate
函数的示例,但我无法让任何东西发挥作用。

我认为解决方案是复制

navigationRef.navigate()
方法(在此处定义)的键入,然后将其简单地应用到包装函数:

// navigationRef.navigate() typing...
//
// navigate<RouteName extends keyof ParamList>(
//   ...args: undefined extends ParamList[RouteName]
//     ? [screen: RouteName] | [screen: RouteName, params: ParamList[RouteName]]
//     : [screen: RouteName, params: ParamList[RouteName]]
// ): void;


type ParamList = RootStackParamList;
type Navigate = <RouteName extends keyof ParamList>(
  ...args: undefined extends ParamList[RouteName]
    ? [screen: RouteName] | [screen: RouteName, params: ParamList[RouteName]]
    : [screen: RouteName, params: ParamList[RouteName]]
) => void;

export const navigate: Navigate = (name, params) => {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
}

// or...

export const navigate: typeof navigationRef.navigate = (name, params) => {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
}

不幸的是,出现以下错误:

Argument of type '[(undefined extends RootStackParamList[RouteName] ? [screen: RouteName] | [screen: RouteName, params: RootStackParamList[RouteName]] : [screen: ...])[0], (undefined extends RootStackParamList[RouteName] ? [screen: ...] | [screen: ...] : [screen: ...])[1]]' is not assignable to parameter of type 'undefined extends RootStackParamList[(undefined extends RootStackParamList[RouteName] ? [screen: RouteName] | [screen: RouteName, params: RootStackParamList[RouteName]] : [screen: ...])[0]] ? [screen: ...] | [screen: ...] : [screen: ...]'.ts(2345)
typescript react-native react-navigation react-navigation-v6
5个回答
7
投票

除了

navigationRef.navigate(name, params)
,你可以尝试用这个

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

export function navigateTo(routeName: string, params?: object) {
  if (navigationRef.isReady()) {
    navigationRef.dispatch(CommonActions.navigate(routeName, params));
  }
}

这对我有用


1
投票

这对我有用

export const navigate = (name: keyof RootStackParamList) => {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name)
  }
}

更好:

export const navigate = (
  name: keyof RootStackParamList,
  params?: StackScreenProps<RootStackParamList>['route']['params']
) => {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params)
  }
}

0
投票

您可以重复使用

navigationRef.navigate

的类型
export const navigate: typeof navigationRef.navigate = (name, params) => {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
}

0
投票

试试这个:

export const navigate: typeof navigationRef.navigate = (name, params?) => {
  if (navigationRef.isReady()) {
    navigationRef.navigate(name, params);
  }
};

0
投票

这对我有用:

// Overload Functions for multiple arguments conditions
export function navigate<RouteName extends keyof RootStackParamList>(
  ...args: // this first condition allows us to iterate over a union type
  // This is to avoid getting a union of all the params from `RootStackParamList[RouteName]`,
  // which will get our types all mixed up if a union RouteName is passed in.
  RouteName extends unknown
    ? // This condition checks if the params are optional,
      // which means it's either undefined or a union with undefined
      undefined extends RootStackParamList[RouteName]
      ?
          | [screen: RouteName] // if the params are optional, we don't have to provide it
          | [screen: RouteName, params: RootStackParamList[RouteName]]
      : [screen: RouteName, params: RootStackParamList[RouteName]]
    : never
): void;
export function navigate<RouteName extends keyof RootStackParamList>(
  options: RouteName extends unknown
    ?
        | {
            key: string;
            params?: RootStackParamList[RouteName];
            merge?: boolean;
          }
        | {
            name: RouteName;
            key?: string;
            params: RootStackParamList[RouteName];
            merge?: boolean;
          }
    : never,
): void;

export function navigate(...args: any[]): void {
  const [screen, params] = args;
  navigationRef.navigate(screen, params);
}
© www.soinside.com 2019 - 2024. All rights reserved.