typescript - 如何使用 Typescript 构建 React Native 导航以进行属性传递
问题描述
我有一个简单的 React Native 应用程序,我正在使用 Typescript 组合在一起,我正在尝试了解如何使导航正常工作。
I a list of content sections and when one is selected to open the chosen article in a webview. 我无法理解的是我应该如何将 webview 的 URL 传递到包含它的视图中。导航列表和 Web 视图在被选中时都应该填满屏幕。
就目前情况而言,我的基本组件GuidanceNavigation
包含一个Stack.Navigator
用于Stack.Screen
列出NavigationItems
所有主题的视图和一个Stack.Screen
用于InstructionView
包含 web 视图以显示说明的视图。
就目前情况而言,这些都是React.Component
类型,我不清楚的部分是,当我在NavigationItems
视图中时,我选择了一个选项,并且我需要父视图将视图替换为NavigationItems
,并InstructionView
提供InstructionView
所选的标题和文件位置文章。据我所知,React Navigation 做了一些涉及传递一些导航属性的魔法,但我无法弄清楚这应该如何在 Typescript 上下文中工作,或者我如何通过 Stack Navigator 传递我的类型化对象,甚至是否Stack Navigator 是在这种情况下使用的正确组件。特定于Typescript 的文档讨论了通过导航属性,但没有解释这与navigator
似乎在 JavaScript 中可用于实际执行导航的对象。
我的代码看起来像这样,自从我使用 React 和我第一次使用 react-native 以来已经有一段时间了,所以它可能既不优秀也不惯用:
GuidanceNavigation.tsx:
const Stack = createStackNavigator();
export class GuidanceNavigation extends React.Component<{}, {}> {
render(): JSX.Element {
return (
<SafeAreaView style={styles.container} >
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Choose a topic" component="NavigationItems" />
<Stack.Screen name="Instructions" component="InstructionView" />
</Stack.Navigator>
</NavigationContainer>
</SafeAreaView>
);
};
}
导航类型.ts:
export interface IFileLink {
title: string,
file: string
}
NavigationItems.tsx:
import { IFileLink } from './NavigationTypes';
export class NavigationItems extends React.Component<{}, {}> {
itemId: number = 0;
readonly items = [
{
section: R.strings.menu_steps,
values: [
{ title: R.strings.menu_getting_started, file: "./assets/html/getting-started.html" },
// and so on
]
},
{
section: R.strings.menu_guidance,
values: [
{ title: R.strings.menu_glossary, file: "./assets/html/glossary.html" },
// etc
]
}
];
itemList(itemList: Array<IFileLink>): JSX.Element[] {
return itemList.map((it) => this.item(it));
};
navigateToFile(link:IFileLink) {
console.log("Navigation to "+link.title);
// This does not work because navigation comes from ??? somewhere???
navigation.navigate('Instructions', link);
};
item(fileLink:IFileLink): JSX.Element {
return(
<Button
key= { this.itemId++ }
title= { fileLink.title }
onPress= {() =>
this.navigateToFile(fileLink)
}
/>
);
};
render(): JSX.Element {
return (
<ScrollView>
<Text style={styles.sectionTitle}>{this.items[0].section}</Text>
{this.itemList(this.items[0].values)}
<Text style={styles.sectionTitle}>{this.items[1].section}</Text>
{this.itemList(this.items[1].values)}
</ScrollView>
)
};
}
指令视图.tsx:
import { IFileLink } from './NavigationTypes';
export class InstructionView extends React.Component<IFileLink> {
private fileLink: IFileLink;
constructor(fl: IFileLink) {
super(fl);
this.fileLink = fl;
}
render(): JSX.Element {
return (
<WebView
source={{ uri: this.fileLink.file }}
/>
);
}
}
当在该列表中选择项目时,如何确保使用所需的属性从NavigationItems
到 导航?InstructionView
解决方案
这不起作用,因为
navigation
来自 ??? 某处???
navigation
对象来自props
组件的。当您的组件通过 加载时Stack.Screen
,react-navigation 会使用 propsroute
和navigation
.
在打字稿方面,您需要声明必须使用此道具调用NavigationItems
组件。你如何做到这一点就是你在文档中看到的解释。navigation
您声明一个RootStackParamList
类型,将您的屏幕名称映射到所需的道具。
type RootStackParamList = {
['Choose a topic']: undefined; // no required props
Instructions: IFileLink; // requires an IFileLink as props
};
您在创建Stack
实例时将此类型用作泛型。
const Stack = createStackNavigator<RootStackParamList>();
navigation
当您声明组件的prop类型时,您再次将此类型用作泛型NavigationItems
。现在你的组件知道它会有一个 prop navigate
,所以你可以调用this.props.navigate
. 它还知道有关您可以导航到的位置的非常详细的信息。屏幕名称必须是,'Choose a topic'
否则'Instructions'
您将收到错误消息。它还知道所有屏幕的独特道具要求,因此如果您尝试导航到Instructions
而不传递 anIFileLink
作为第二个参数,则会出现错误。
import { StackNavigationProp, createStackNavigator } from '@react-navigation/stack';
type ItemsProps = {
navigation: StackNavigationProp<RootStackParamList, 'Choose a topic'>;
};
export class NavigationItems extends React.Component<ItemsProps, {}> {
navigateToFile(link: IFileLink) {
console.log("Navigation to " + link.title);
// can now navigate via props
this.props.navigation.navigate('Instructions', link);
};
/*...*/
}
您的Navigator
. 您需要传递组件本身,而不是它们的string
名称。
<Stack.Screen name="Choose a topic" component={NavigationItems} />
<Stack.Screen name="Instructions" component={InstructionView} />
推荐阅读
- javascript - 如何使用 React Router 将 div 放入 Switch 中?
- c# - C# WMI 读数:Win32_PerfRawData_Tcpip_NetworkInterface 不返回任何内容
- php - 在 Laravel 中将方法中的参数类型定义为模型的集合
- mysql - Maria DB GROUP BY id DESC 和 IN 魔法
- angular - 找不到模块“rxjs-compat/Observable”
- google-analytics - google 如何在 Bigquery/Google-Analytics 中设置 fullVisitorId/Client ID?
- python - 熊猫:在另一列的标志之间标记值
- android - 在 Android 上带有彩色边框的 Xamarin 表单条目
- php - 将嵌套对象链存储在变量中
- swift - 字符串问题的时间戳?