我的代码在成功登录时出现错误,但没有重定向到主屏幕。 我不知道我的代码发生了什么。我认为问题是我的年轻代码,并且真的不知道如何解决这个问题。 请帮助我修复我的代码。谢谢!
StackNavigation.js
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import React, { useState, useEffect } from 'react'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Startup_screen from '../screens/Begin/Startup_screen';
import Authorization from '../screens/Begin/Authorization';
import Home from '../screens/Main/HomeTab/Home';
import { COLOR, ICON } from '../constants/Theme';
import { appStyle, windowHeight } from '../constants/AppStyle';
import Registration from '../screens/Begin/Registration';
import MyorderCurrent from '../screens/Main/HistoryTab/MyorderCurrent';
import MyorderHistory from '../screens/Main/HistoryTab/MyorderHistory';
import { Image, Text, View } from 'react-native';
import Account from '../screens/Main/ProfileTab/Account';
import Forgot_password from '../screens/Begin/Forgot_password';
import MyCart from '../screens/Main/HomeTab/MyCart';
import UpdateAccount from '../screens/Main/ProfileTab/UpdateAccount';
import Reward from '../screens/Main/ProfileTab/Reward';
import OrderDetail from '../screens/Main/HomeTab/OrderDetail';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
const StackBegin = () => {
return (
<Stack.Navigator
initialRouteName="Start"
screenOptions={{ headerShown: false }}>
<Stack.Screen name='Start' component={Startup_screen} />
{props => <Startup_screen {...props} />}
<Stack.Screen name='Authorization' component={Authorization} />
{props => <Authorization {...props} />}
<Stack.Screen name='Registration' component={Registration} />
{props => <Registration {...props} />}
<Stack.Screen name='ForgotPassword' component={Forgot_password} />
{props => <Forgot_password {...props} />}
</Stack.Navigator>
)
};
const StackHome = () => {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Home" component={Home}></Stack.Screen>
<Stack.Screen name="MyCart" component={MyCart}></Stack.Screen>
<Stack.Screen name="OrderDetail" component={OrderDetail} />
</Stack.Navigator>
);
};
const StackHistory = () => {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="MyorderCurrent" component={MyorderCurrent}></Stack.Screen>
<Stack.Screen name="MyorderHistory" component={MyorderHistory}></Stack.Screen>
</Stack.Navigator>
);
};
const StackProfile = () => {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Account" component={Account}></Stack.Screen>
<Stack.Screen name="UpdateAccount" component={UpdateAccount}></Stack.Screen>
<Stack.Screen name="Reward" component={Reward}></Stack.Screen>
</Stack.Navigator>
)
};
const Main = ({ name }) => {
return (
<Tab.Navigator
initialRouteName="StackHome"
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName, label;
if (route.name === 'StackHome') {
iconName = focused ? ICON.HomeFocus : ICON.Home;
label = "Trang chủ";
} else if (route.name === 'StackHistory') {
iconName = focused ? ICON.HistoryFocus : ICON.History;
label = "Lịch sử";
} else if (route.name === 'StackProfile') {
iconName = focused ? ICON.AccountFocus : ICON.Account;
label = "Hồ sơ";
}
return (
<View
style={{
flex: 1,
alignItems: 'center',
marginTop: 10,
}}>
<View>
<Image
source={iconName}
style={{
width: 26,
height: 26,
resizeMode: 'stretch',
tintColor: focused ? COLOR.primary : COLOR.grayText,
}}
/>
</View>
<Text
style={{
fontSize: 10,
fontWeight: 600,
marginTop: 4,
color: focused ? COLOR.primary : COLOR.grayText,
}}>
{label}
</Text>
</View>
);
},
tabBarHideOnKeyboard: true,
headerShown: false,
tabBarShowLabel: false,
tabBarStyle: {
height: windowHeight * 0.075,
position: 'absolute',
backgroundColor: COLOR.background,
},
})}
>
<Tab.Screen name="StackHome" component={StackHome} initialParams={{ name }} />
{props => <StackHome {...props} />}
<Tab.Screen name="StackHistory" component={StackHistory} />
{props => <StackHistory {...props} />}
<Tab.Screen name="StackProfile" component={StackProfile} />
{props => <StackProfile {...props} />}
</Tab.Navigator>
)
};
const StackNavigation = () => {
const [isLogin, setIsLogin] = useState(false);
return (
<>
{
isLogin ? <Main/> : <StackBegin />
}
</>
)
}
export default StackNavigation;
授权.js
const Authorization = () => {
const navigation = useNavigation();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLogin, setIsLogin] = useState(false);
const handleLogin = async () => {
try {
const response = await axios.post('http://10.0.2.2:3000/users/login', {
email: email,
password: password
});
console.log('Server response:', response.data);
if (response.data && response.data.token) {
// Lưu trữ token vào AsyncStorage
await AsyncStorage.setItem('userToken', response.data.token);
setIsLogin(true);
Alert.alert('Login successful');
const storedToken = await AsyncStorage.getItem('userToken');
console.log('Stored token:', storedToken);
} else {
Alert.alert('Login failed', 'Token not found in server response');
}
} catch (error) {
console.log('Login error:', error);
if (error.response && error.response.data) {
Alert.alert('Login failed', error.response.data.message);
} else {
Alert.alert('Login failed', 'An error occurred during login.');
}
}
};
const handleSignUp = () => {
navigation.navigate('Registration');
};
const handleForgot = () => {
navigation.navigate('ForgotPassword');
};
return (
<SafeAreaView style={appStyle.container}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<FastImage resizeMode="stretch" source={ICON.Back} style={appStyle.icon} />
</TouchableOpacity>
<View style={{ marginTop: windowHeight * 0.06, marginBottom: windowHeight * 0.04 }}>
<Text style={appStyle.text24}>Sign in</Text>
<Text style={[appStyle.text16, { color: COLOR.lightText, marginTop: 27 }]}>Welcome back</Text>
</View>
{/* INPUT EMAIL */}
<View style={[styles.viewRow]}>
<View style={styles.rowbetween}>
<FastImage tintColor={COLOR.primary} resizeMode="stretch" source={ICON.Mail} style={[appStyle.icon, { width: 26 }]} />
<Text style={{ fontSize: 35, color: COLOR.lightText, fontWeight: '200' }}>|</Text>
</View>
<TextInput
style={{ marginLeft: 25 }}
placeholder="Email address"
placeholderTextColor='#C1C7D0'
fontSize={16}
value={email}
onChangeText={setEmail}
>
</TextInput>
</View>
{/* INPUT PASSWORD */}
<View style={[styles.viewRow]}>
<View style={styles.rowbetween}>
<FastImage tintColor={COLOR.primary} resizeMode="stretch" source={ICON.Lock} style={[appStyle.icon, { height: 26 }]} />
<Text style={{ fontSize: 35, color: COLOR.lightText, fontWeight: '200' }}>|</Text>
</View>
<TextInput
style={styles.input}
placeholderTextColor='#C1C7D0'
placeholder="Password"
fontSize={16}
value={password}
onChangeText={setPassword}
secureTextEntry
>
</TextInput>
<TouchableOpacity>
<FastImage tintColor={COLOR.primary} resizeMode="stretch" source={ICON.Eye} style={[appStyle.icon, { width: 26 }]} />
</TouchableOpacity>
</View>
{/* FORGOT PASSWORD */}
<TouchableOpacity
onPress={() => handleForgot()}
style={{ width: windowWidth * 0.32, alignSelf: 'center', borderBottomWidth: 1, borderColor: COLOR.primary, marginTop: 30 }}>
<Text style={[appStyle.text16Bold, { color: COLOR.primary }]}>Forgot Password?</Text>
</TouchableOpacity>
{/* BUTTON SIGN IN */}
<View style={styles.next}>
<AppButton
icon={ICON.Next}
width={70}
height={70}
borderRadius={35}
onPress={handleLogin}
/>
</View>
{/* SIGN UP */}
<View style={styles.form3}>
<Text style={styles.title3}>New member?</Text>
<TouchableOpacity onPress={() => handleSignUp()}>
<Text style={styles.title4}>Sign up</Text>
</TouchableOpacity>
</View>
</SafeAreaView>
)
}
export default Authorization
我尝试了一切方法来解决这个问题,但效果不佳
这就是我处理导航的方式。请参考,
登录.js
import React, { useState,useRef } from 'react'
import { View,SafeAreaView,Image,ActivityIndicator,StatusBar } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler';
import axios from 'axios';
import { DataTable, Divider, TextInput,Button,Text } from 'react-native-paper';
import Footer from '../Templates/Footer';
import ApiPath from '../../resources/ApiPath';
import Styles from '../../resources/Style';
import {setStorage} from '../../resources/Utill';
import {showError,showSuccess} from '../../resources/Notice/ErrorMessage';
import Logo from '../../resources/images/logo.jpg';
import OfflineNotice from '../../resources/Notice/OfflineNotice';
import { useLogin } from '../Navigation/LoginProvider';
const Login = ({navigation}) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [isloading, setisLoading] = useState(false)
const inputRef = useRef();
const {setIsLoggedIn} = useLogin();
const handleButtonClick = () => {
inputRef.current.focus();
}
funcLogin= async()=>{
if(!username.trim()) {
showError("Username required");
return false
}
if(!password.trim()){
showError("Password required");
return false
}
try{
let path = ApiPath.getAuthLogin();
setisLoading(true);
axios.post(path, {
user: username,
pwd: password,
}).then( function (response) {
if(response.data.msg == 1){
setStorage(response.data);
setisLoading(false)
setIsLoggedIn(true)
// navigation.navigate('app');
}
else if(response.data.msg == 0){
showError(response.data.message);
setisLoading(false)
handleButtonClick();
setIsLoggedIn(false)
}
else{
// navigation.navigate('auth');
setisLoading(false)
setIsLoggedIn(false)
}
}).catch((error) => {
showError('Error: ' + error)
});
}catch (error){
showError('Error: ' + error)
// navigation.navigate('auth');
setisLoading(false)
setIsLoggedIn(false)
}
}
return (
<SafeAreaView style={Styles.root}>
<StatusBar barStyle="light-content" backgroundColor="#b61b1b" />
<OfflineNotice/>
<View style={Styles.logocontainer}>
<Image source={Logo} style={Styles.logo} resizeMode="contain" />
</View>
<Text variant="titleLarge" style={Styles.heading}>Parliament of Sri Lanka.</Text>
<View style={Styles.container}>
<TextInput label="Username" mode="outlined" style={{width:'80%'}} onChangeText={(username) => setUsername(username.toLowerCase())} ref={inputRef} />
</View>
<View style={Styles.container}>
<TextInput label="Password" mode="outlined" style={{width:'80%' }} onChangeText={(password) => setPassword(password)} secureTextEntry={true} ref={inputRef}/>
</View>
<View style={{alignItems:'center', paddingTop:10}}>
<Button mode="elevated" onPress={() =>funcLogin()} style={{ width:'80%'}} buttonColor="#3377FF" textColor="#fff" >
{(setisLoading===true ? 'Loading' : 'Login' )}
</Button>
{(isloading ?
<View>
<ActivityIndicator/>
</View>
: '')}
</View>
<Footer/>
</SafeAreaView>
)
}
export default Login
这里我使用了
useContext
hook 来维持我的 loggedIn
状态。在您的代码中您还设置了 setIsLogin(true);
但你已经使用了 useState
Hook。它不是在全球范围内管理状态。请参考useContext
在这里我检查了用户令牌。
LoginProvider.js
import React,{ createContext, useContext, useState, useEffect} from 'react'
import { View, Text } from 'react-native'
import AsyncStorage from '@react-native-async-storage/async-storage';
const LoginContext = createContext();
const LoginProvider = ({children}) => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
useEffect(async()=>{
const token= await AsyncStorage.getItem('userToken')
console.log(token)
(token ? setIsLoggedIn(true) : setIsLoggedIn(false))
},[])
return (
<LoginContext.Provider value={{isLoggedIn, setIsLoggedIn}}>
{children}
</LoginContext.Provider>
)
}
export const useLogin = () => useContext(LoginContext)
export default LoginProvider
现在我已经根据它检查了
setIsLoggedIn
真或假,我渲染了导航。我有一个名为 Appstack
的抽屉式导航和堆栈导航 Authstack
路线.js
import React, { Component, useEffect, useState } from 'react';
import { NavigationContainer} from '@react-navigation/native';
import 'react-native-gesture-handler';
import AuthStack from './Authstack';
import AppStack from './Appstack';
import { useLogin } from './LoginProvider';
function Route() {
const {isLoggedIn, setIsLoggedIn} = useLogin()
return (
<NavigationContainer >
{(isLoggedIn ? <AppStack/> : <AuthStack/>) }
</NavigationContainer>
);
}
export default Route;
希望你能得到一个想法