如何解决console.error:“使用有效载荷导航的操作...未处理...”
我在“ LoginComponent”中的“ onLogin”功能有问题。按下处理该功能的TouchableOpacity之后,我希望将用户定向到“ HomeComponent”,但我却得到了这个console.error:“使用有效内容导航的操作...未处理...”任何人都知道为什么会这样呢?任何帮助将不胜感激。谢谢!
import React,{ Component } from 'react';
import 'react-native-gesture-handler';
import { createStackNavigator } from '@react-navigation/stack';
import WelcomeScreen from './WelcomeComponent';
import LoginScreen from './LoginComponent';
import RegisterScreen from './RegisterComponent';
import HomeScreen from './HomeComponent';
import { NavigationContainer } from '@react-navigation/native';
import { createMaterialBottomTabNavigator } from '@react-navigation/material-bottom-tabs';
import { AsyncStorage } from 'react-native';
const AuthStack = createStackNavigator();
const AuthStackScreen = () => {
return <AuthStack.Navigator initialRouteName="Welcome">
<AuthStack.Screen name="Welcome" component={WelcomeScreen} />
<AuthStack.Screen name="Login" component={LoginScreen} />
<AuthStack.Screen name="Register" component={RegisterScreen} />
</AuthStack.Navigator>
};
const HomeTab = createMaterialBottomTabNavigator();
const HomeTabScreen = () => {
return <HomeTab.Navigator initialRouteName="Home">
<HomeTab.Screen name="Home" component={HomeScreen} />
</HomeTab.Navigator>
}
class Navigation extends Component {
constructor(props) {
super(props);
this.state = {
isLoggedIn: false,};
this.loginStatusCheck();
}
loginStatusCheck = async () => {
const userToken = await AsyncStorage.getItem("userprofile");
if(userToken) {
this.setState({ isLoggedIn: true })
} else {
this.setState({ isLoggedIn: false })
}
}
render() {
return(
<NavigationContainer>
{this.state.isLoggedIn ? <AuthStackScreen /> : <HomeTabScreen />}
</NavigationContainer>
);
};
};
export default Navigation;
import React,{ Component } from 'react';
import { StyleSheet,SafeAreaView,ScrollView,View,TouchableOpacity,Text,Linking,AsyncStorage } from 'react-native';
import { Input,CheckBox } from 'react-native-elements';
import { FontAwesome } from '@expo/vector-icons';
class LoginScreen extends Component {
constructor(props) {
super(props);
this.state = {
username: "",password:"",token: "",remember: false
};
this.getData();
};
handleUsernameChange = username => {
this.setState({ username })
};
handlePasswordChange = password => {
this.setState({ password })
};
onLogin = async () => {
try {
await AsyncStorage.setItem("userprofile",JSON.stringify({ username: this.state.username,password: this.state.password }));
this.props.navigation.navigate("Home",{
screen: "HomeScreen",});
} catch (err) {
console.log(err);
}
};
getData = async () => {
try {
const userprofile = await AsyncStorage.getItem("userprofile");
const userProfile = JSON.parse(userprofile);
if (userProfile !== null) {
this.setState({ ...userProfile })
}
if (username !== null) {
this.setState({ username })
}
if (password !== null) {
this.setState({ password })
}
} catch (err) {
console.log(err);
}
}
render() {
const { username,password } = this.state;
return (
<SafeAreaView style={styles.container}>
<ScrollView>
<Text style={styles.titleText}>Login</Text>
<Text style={styles.fillerText}>Hi there! Nice to see you again.</Text>
<Input
inputStyle={{color: 'white'}}
placeholder="Enter username"
onChangeText={this.handleUsernameChange}
value={username}
keyboardType="email-address"
autoCapitalize="none"
leftIcon={{ type: 'font-awesome',name: 'user-circle-o',color: 'white',marginRight: 10 }}
/>
<Input
inputStyle={{color: 'white'}}
placeholder="Password"
secureTextEntry
onChangeText={this.handlePasswordChange}
value={password}
leftIcon={{ type: 'font-awesome',name: 'lock',marginRight: 10 }}
/>
<CheckBox
title="Remember Me"
checked={this.state.remember}
onPress={() => this.setState({remember: !this.state.remember})}
containerStyle={styles.rememberCheckbox}
textStyle={{color: 'white'}}
checkedColor="crimson"
/>
<TouchableOpacity
style={styles.loginButton}
title="Login" type="submit"
onPress={this.onLogin}
>
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
<Text style={{textAlign: 'center',color: 'grey',marginTop: 20}}>
OR use an account from one of the following:
</Text>
<View style={styles.buttonsContainer}>
<TouchableOpacity style={styles.twitterButton}>
<FontAwesome name="twitter" color="white" style={{marginRight: 5}}/>
<Text style={{color: 'white'}}>Twitter</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.facebookButton}>
<FontAwesome name="facebook-square" color="white" style={{marginRight: 5}}/>
<Text style={{color: 'white'}}>Facebook</Text>
</TouchableOpacity>
</View>
<View style={{alignItems: 'center'}}>
<TouchableOpacity style={styles.googleButton}>
<FontAwesome name="google" color="black" style={{marginRight: 5}}/>
<Text style={{color: 'grey'}}>Google</Text>
</TouchableOpacity>
</View>
<View style={styles.linkContainer}>
<TouchableOpacity style={{marginTop: 75}} onPress={() => Linking.openURL('#')}>
<Text style={{color: 'white'}}>
Forgot Your Password?
</Text>
</TouchableOpacity>
<TouchableOpacity style={{marginTop: 75,marginLeft: 210}} onPress={() => Linking.openURL('#')}>
<Text style={{color: 'white'}}>
Register
</Text>
</TouchableOpacity>
</View>
</ScrollView>
</SafeAreaView>
);
};
};
const styles = StyleSheet.create({
container: {
flex: 1,justifyContent: 'center',backgroundColor: 'black'
},buttonsContainer: {
flex: 2,alignItems: 'center',flexDirection: 'row'
},linkContainer: {
flex: 3,titleText: {
fontSize: 26,marginBottom: 30,marginTop: 20
},fillerText: {
color: 'grey',marginBottom: 20
},loginButton: {
backgroundColor: 'crimson',paddingVertical: 17,paddingHorizontal: 25,borderRadius: 20,textAlign: 'center'
},buttonText: {
color: 'white',fontSize: 18,twitterButton: {
backgroundColor: '#00acee',marginTop: 20,padding: 10,width: '40%',marginLeft: 20,flexDirection: 'row',borderRadius: 20
},facebookButton: {
backgroundColor: '#4267B2',googleButton: {
backgroundColor: '#FFFFFF',rememberCheckbox: {
margin: 10,marginBottom: 20,backgroundColor: null
}
});
export default LoginScreen;
解决方法
我认为在navigate
组件中不必使用LoginScreen
,因为您已经编写了代码,可以根据isLoggedIn
的值有条件地呈现两个导航器。 / p>
当前实现中缺少的是一种从isLoggedIn
组件内部更新LoginScreen
的方法。然后,如果isLoggedIn
被更新并设置为true
,则Navigation
组件将被重新渲染,并且显示HomeScreen
组件而无需导航。
我选择在这里使用react context,但是如果您愿意的话,也可以将这种方法与redux之类的方法一起使用。使用类似react context之类的原因是为了能够在组件之间轻松传递isLoggedIn
及其设置器。
我将给出一个更通用的示例,因为这样更容易说明这种方法:
// Imports and other stuff...
const LoginContext = React.createContext([null,() => {}]);
const LoginContextProvider = props => {
const [isLoggedIn,setIsLoggedIn] = React.useState(false);
return (
<LoginContext.Provider value={[isLoggedIn,setIsLoggedIn]}>
{props.children}
</LoginContext.Provider>
);
};
const HomeScreen = () => {
return (
<View>
<Text>HomeScreen</Text>
</View>
);
};
const LoginScreen = () => {
const [isLoggedIn,setIsLoggedIn] = React.useContext(LoginContext);
return (
<View>
<Text>LoginScreen</Text>
<Button
title="login"
onPress={() => {
setIsLoggedIn(true);
}}
/>
</View>
);
};
const HomeTabScreen = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
</Tab.Navigator>
);
};
const AuthStackScreen = ({ navigation }) => {
return (
<Stack.Navigator>
<Stack.Screen name="Login" component={LoginScreen} />
</Stack.Navigator>
);
};
const Navigation = () => {
const [isLoggedIn,setIsLoggedIn] = React.useContext(LoginContext);
return (
<NavigationContainer>
{isLoggedIn ? <HomeTabScreen /> : <AuthStackScreen />}
</NavigationContainer>
);
};
export default function App() {
return (
<LoginContextProvider>
<Navigation />
</LoginContextProvider>
);
}
因此,上面显示的方法是创建一个保存您的isLoggedIn
状态和设置器(setIsLoggedIn
)的提供程序。然后,当我们使用此提供程序包装Navigation
时,便可以从提供程序内部的任何组件访问isLogged
和setIsLoggedIn
,从而允许我们更新{{1 }} 零件。此状态更新后,提供者及其内部的所有内容(即isLogged
)将重新呈现并显示LoginScreen
组件。
通常,惯例是将大多数与React上下文相关的内容放入其自己的文件中,并将部件导入所需的组件中,但是出于演示目的,我没有这样做。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。