react-native - 使用 React Native 中的 React Navigation 将状态从主 App.js 传递到屏幕组件
问题描述
我正在制作一个反应原生的小应用程序,它是一个基本的登录工作流程,它使用几个屏幕(登录和主页),根据用户状态显示;在 App.js 中,我有一堆状态用于启用/禁用视图、按钮、显示用户名等。我在外部组件中有登录屏幕和主屏幕。我想知道(除了使用上下文)是否有办法让这些状态(和功能)可用于子屏幕
这是我的代码的一部分:
应用程序.js
export default function App() {
const [isLoading, setIsLoading] = useState(true);
const [isLogged, setIsLogged] = useState(false);
const [userToken, setUserToken] = useState(null);
const [userProfile, setUserProfile] = useState(null);
const [email, setEmail] = useState(null);
const [password, setPassword] = useState(null);
const [loggingIn, setloggingIn] = useState(false);
const [error, setError] = useState(null);
const AppStack = createStackNavigator();
useEffect(() => {
AsyncStorage.getItem('userProfile').then((value) => {
if (value) {
console.log(JSON.parse(value)),
setUserProfile(JSON.parse(value)),
setIsLoading(false),
setIsLogged(true);
} else {
setIsLoading(false), setIsLogged(false);
}
});
}, []);
const doLogout = async () => {
---- LOGOUT CODE
}
const doLogin = async () => {
----- LOGIN CODE and UPDATE of state and asyncstorage
}
return (
<NavigationContainer>
<AppStack.Navigator initialRouteName="Login">
<AppStack.Screen name="Login" component={Login} />
<AppStack.Screen
name="Home"
component={Home}
options={{ headerShown: false }}
/>
</AppStack.Navigator>
</NavigationContainer>
);
登录.js
const Login = ({ loggingIn, userProfile }) => {
console.log(userProfile);
return (
<View style={styles.container}>
<Button
title="Login to Site"
onPress={() => doLogin()}
disabled={loggingIn}
>
{userProfile && userProfile.name} Login to Site
</Button>
</View>
);
};
如何访问我在 App.js 中设置和创建(和更新)的 loggingIn(甚至 userProfile)和 doLogin() 函数?对于像这样的简单用途,应该有一种简单的方法(除了useContext)。
解决方案
您可以将参数传递给路由。请参阅此处的第一部分:
https://reactnavigation.org/docs/params/
但是您可能希望将状态移动到其相关的屏幕组件或其他反应组件。然后,在父组件中,将值传递给子组件。请参阅下面的 TestComponent.js。然后,在子组件中,我们可以使用从父组件传入的 props。请参阅下面的 TestChildComponent.js。
我还提供了 App.js、TestNavigator.js 和 TestScreen.js,因此您可以复制/粘贴它们并自己测试。
此外,如果您发现自己使用 useState 挂钩管理的状态太多,那么您可以考虑使用Redux进行状态管理,而不是使用 useState 挂钩。
下面的代码:
测试组件.js:
import React, {useState} from "react";
import {View, StyleSheet} from "react-native";
import ChildComponent from "./TestChildComponent";
const TestComponent = props => {
const [value, setValue] = useState("Bilbo");
return (
<View style={styles.container}>
<ChildComponent value={value} setValue={setValue} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
margin: 100,
},
});
export default TestComponent;
TestChildComponent.js:
import React from "react";
import {StyleSheet, Text, Button, View} from "react-native";
const ChildComponent = props => {
const buttonPressHandler = () => {
props.setValue("Frodo");
};
return (
<View style={styles.child}>
<Text>Press Me:</Text>
<Button title={props.value} onPress={buttonPressHandler} />
</View>
);
};
export default ChildComponent;
const styles = StyleSheet.create({
child: {
flexDirection: "row",
marginHorizontal: 25,
justifyContent: "center",
alignItems: "center",
},
});
测试导航器.js:
import React from "react";
import {createStackNavigator} from "@react-navigation/stack";
import TestScreen from "./TestScreen";
const TestStackNavigator = createStackNavigator();
export const TestNavigator = () => {
return (
<TestStackNavigator.Navigator>
<TestStackNavigator.Screen name={"Test"} component={TestScreen}/>
</TestStackNavigator.Navigator>
);
};
应用程序.js
import React from 'react';
import {StyleSheet, SafeAreaView} from 'react-native';
import {NavigationContainer} from "@react-navigation/native";
import {TestNavigator} from "./TestNavigator";
export default function App() {
return (
<NavigationContainer>
<SafeAreaView style={styles.safeAreaView}>
<TestNavigator />
</SafeAreaView>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
safeAreaView: {
flex: 1,
}
});
测试屏幕.js
import React from "react";
import TestComponent from "./TestComponent";
const TestScreen = props => {
return (
<TestComponent />
);
};
export default TestScreen;
推荐阅读
- azure-api-management - Azure API 管理开发人员门户中的 API 特定页面
- php - PHP文件格式上传
- javascript - Intersectionobserver 和 InnerHTML 的无限滚动
- python - 每组随机样本,min_rows
- huawei-mobile-services - 使用 HMS Video Kit 更新 HMS Core APK 时出现错误代码 103
- r - 如何制作 y 轴计数值的堆积条形图>
- asp.net-core - 运行时来自模板的新 ASP.NET 核心应用程序给出“无法访问此站点”
- javascript - 当同一资源的 http2 推送正在进行时触发 GET 请求时会发生什么
- reactjs - 找不到模块 reactjs
- hyperledger-fabric - Hyperledger Fabric:如何使用基于 HDD/SSD 的 I/O 绑定事务在 LevelDB 中获得性能差异?