sev*_*ven 3 javascript typescript reactjs react-native react-navigation
如何正确键入作为道具传递给另一个组件的导航?根据文档
应用程序中的每个屏幕组件都会自动提供导航道具。
并且,
要对我们的屏幕进行类型检查,我们需要注释屏幕接收到的导航属性和路线属性。
type Props = NativeStackScreenProps<RootStackParamList, 'Profile'>;
Run Code Online (Sandbox Code Playgroud)
我有一个带有路由器的导航组件:
const App: React.FC = () => {
const [userMetrics, setUserMetrics] = useState<UserMetrics>(null);
const Stack = createNativeStackNavigator<RootStackParamList>();
return (
<UserMetricsContext.Provider value={{ userMetrics, setUserMetrics }}>
<NavigationContainer>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Tests" component={Tests} />
</Stack.Navigator>
</NavigationContainer>
</UserMetricsContext.Provider>
);
};
Run Code Online (Sandbox Code Playgroud)
在主屏幕中,我想接收导航道具以将其进一步传递到表单,该表单有一个按钮,该按钮将导航到测试组件并将表单数据作为参数传递:
interface Props {
navigation: NativeStackScreenProps<RootStackParamList, "Home">;
}
export const Home: React.FC<Props> = ({ navigation }) => {
const { setUserMetrics } =
useContext<IUserMetricsContextType>(UserMetricsContext);
return (
<View style={styles.container}>
<StatusBar style="auto" />
<HealthCheckForm onSubmit={setUserMetrics} navigation={navigation} />
</View>
);
};
Run Code Online (Sandbox Code Playgroud)
现在问题开始在表单组件中显现出来,因为打字稿假设一级太多,我已经像在父 Home 组件中那样输入了 props,如下所示:
interface Props {
onSubmit: React.Dispatch<React.SetStateAction<UserMetrics>>;
navigation: NativeStackScreenProps<RootStackParamList, "Home">;
}
Run Code Online (Sandbox Code Playgroud)
打字稿希望我像这样使用它:
const submitHandler = (data: UserMetrics) => {
onSubmit(data);
navigation.navigation.navigate("Tests", { userMetrics: data });
console.log(data);
};
Run Code Online (Sandbox Code Playgroud)
但这不起作用,正确的工作和导航用法是
navigation.navigate("Tests", { userMetrics: data });
Run Code Online (Sandbox Code Playgroud)
当我导航到测试组件并传递参数时,我不知道如何在测试组件中接收它们。我试图类比地这样做:
interface Props {
navigation: NativeStackScreenProps<RootStackParamList, "Tests">;
}
export const Tests: React.FC<Props> = ({ navigation }) => {
const { userMetrics } =
useContext<IUserMetricsContextType>(UserMetricsContext);
console.log({ params: navigation.route.params });
return (
<View>
<DisplayList />
</View>
);
};
Run Code Online (Sandbox Code Playgroud)
我收到另一个关于读取未定义属性的错误。谢谢
有嵌套导航器的解决方案(起点:https: //reactnavigation.org/docs/nesting-navigators/)。但是,在这种情况下,我建议不要让您HealthCheckForm了解导航状态。只需向其传递一个标准onSubmit()道具并处理组件内的所有导航即可Home。
另外作为提示,请确保正确设置您的路径,RootStackParamList以便“测试”路线符合预期{userMetrics: YourDataType}。这是一个随机设置的例子。
export type RootStackParamList = {
myRouteName: undefined;
tests: { userMetrics: MyDataType }; // TS now expects MyDataType on the props for tests route
terminalAndMate: {
departingTerminal: WSFTerminal;
arrivingTerminal: WSFTerminal;
};
...
Run Code Online (Sandbox Code Playgroud)
我还建议以这种方式输入屏幕道具,而不是作为界面。NativeStackScreenProps 可以携带 rootStackParamList 上定义的参数:
type TestsScreenProps = NativeStackScreenProps<RootStackParamList, "tests">;
Run Code Online (Sandbox Code Playgroud)
通过这两项更改,tests屏幕上应该有props.route.params,其中将包含 MyDataType。
尝试: https: //reactnavigation.org/docs/5.x/typescript/
-关于七号评论的补充-
查看 NativeStackScreenProps 的类型声明。
type TestsScreenProps = NativeStackScreenProps<RootStackParamList, "tests">;
Run Code Online (Sandbox Code Playgroud)
props通过像您一样创建接口,您可以说该组件的类型是
{ navigation: { navigation: NativeStackNavigation..etc , route: RouteProp }}
Run Code Online (Sandbox Code Playgroud)
您可以看到它是双重嵌套的,并且不是必需的,因为库提供的类型支持您需要的所有功能。
onsubmit 你的 onSubmit 函数看起来像这样:
//home.tsx
const onSubmit = (data: YourDataType) => {
props.navigation.navigate("tests", { userMetrics: data});
}
return (
//...stuff
<YourFormComponent onSubmit={onSubmit} />
Run Code Online (Sandbox Code Playgroud)
这样,您的所有导航都由 home 处理,它与测试处于同一“级别”,并且可以使导航更加干净。
不应该需要任何 useEffect 调用。
| 归档时间: |
|
| 查看次数: |
7597 次 |
| 最近记录: |