我有一个Android应用程序运行在模拟器上。我可以“登录”,但我不会被重定向到我的主屏幕,相反,我必须在模拟器上重新加载应用程序,然后我会自动登录。我可以点击一个按钮来注销,但只有当我关闭并重新打开应用程序时,我才真正注销,如果我不关闭并重新打开应用程序,它将保留在同一页面上。
我有以下相关的代码片段:
在App.jsx中:
import React, { useEffect } from 'react'
import { AsyncStorage } from 'react-native'
import moment from 'moment'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
import Login from './modules/Login'
import Home from './modules/Home'
import Nav from './modules/Nav'
import Events from './modules/Events/Events'
import ConsentForm from './modules/ConsentForm'
export default function App() {
const [expired, setExpired] = React.useState(true)
const [consented, setConsented] = React.useState(false)
const Stack = createNativeStackNavigator()
const getData = async () => {
return await AsyncStorage.getItem('@myapp:jwt');
}
useEffect(() => {
getData().then((value) => {
value = JSON.parse(value)
if(value == null){
setExpired(true)
}else{
const now = moment()
setExpired(now.isAfter(moment(value?.expiry)))
setConsented(value?.consented)
}
})
})
return (
<NavigationContainer>
<Stack.Navigator>
{!expired ? (
consented ? (
<>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Nav" component={Nav} />
<Stack.Screen name="Events" component={Events} />
</>
): (
<>
<Stack.Screen name="ConsentForm" component={ConsentForm} />
</>
)
) : (
<>
<Stack.Screen name="Login" component={Login} />
</>
)}
</Stack.Navigator>
</NavigationContainer>
)}
这是我的登录界面:
import React from 'react'
import { *, AsyncStorage} from 'react-native' // imported a bunch of stuff here
import jwt_decode from 'jwt-decode'
import { MY_API_URL } from './constants'
const Login = ({ navigation }) => {
const [username, onChangeUsername] = React.useState(null)
const [password, onChangePassword] = React.useState(null)
const postLoginInformation = () => {
fetch(`${MY_API_URL}/login/`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: username,
password: password,
}),
})
.then(async (res) => {
const response = await res.json()
const jwt = JSON.parse(response).jwt
const decoded_jwt = jwt_decode(jwt)
await AsyncStorage.setItem(
'@myapp:jwt',
JSON.stringify(decoded_jwt),
)
}).catch((e) => console.log('login error', e, `${MY_API_URL}/login/`))
}
return (
<SafeAreaView style={styles.container}>
<!-- more page items in between -->
<TouchableOpacity
onPress={() => postLoginInformation()}
>
<Image
source={require('../images/login/login_button.png')}
/>
</TouchableOpacity>
</SafeAreaView>
)
}
export default Login
我添加了一些控制台语句来查看我何时登录,然而,一旦jwt改变,应用程序就不会“重新加载”--有什么方法可以让它做到这一点吗?很抱歉,这是我第一个react native app。
谢谢!如果您需要更多信息,请告诉我。
2条答案
按热度按时间t5fffqht1#
我的建议是,您手动重定向到登录屏幕时,登录过程是成功的.所以你可以这样做:
您可以将完全相同的逻辑应用于注销过程,只要注销过程成功完成,就重定向到登录页面。
ff29svar2#
这里的问题是你使用
useEffect
来改变expired
变量的值。当
App.jsx
中的任何状态或属性发生变化时,没有任何依赖关系的useEffect
将运行。但问题是当你登录时,App.jsx
中的任何东西都不会改变,所以useEffect
不会运行,屏幕不能从LoginScreen
更改为HomeScreen
。我建议你使用
redux
和react-redux
来创建一个全局状态expired
并修改它的值。