skip to Main Content

I have an android app running on an emulator. I’m able to "log in" but I don’t get redirected to my home screen, instead, I have to reload the app on the emulator and then I am automatically logged in. The same goes for logging out..I can click a button to log out but only when I close and reopen the app am I actually logged out, if I don’t close and reopen the app just remains on the same page.

I have the following relevant snippets of code:

In 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>
      )}

Here is my login screen:

    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

I added some console statements to see when I am logged in, however, the app doesn’t "reload" once the jwt changes – is there some way I can make it do that? Sorry if it’s obvious, this is my first react native app.

Thanks! Let me know if you need more information.

2

Answers


  1. My suggestion is that you manually redirect to Login Screen when login process is successful. So you can do this:

    import { useNavigation } from '@react-navigation/native';
    
    const navigation = useNavigation();
    
    navigation.navigate('Login'); //Add this line where login is successful. 
    

    You can apply the exact same logic to logout process, redirecting to login page whenever the logout process is finished successfully.

    Login or Signup to reply.
  2. The problem here is you use useEffect to change value of expired variable.

    useEffect without any dependencies will run when any state or prop in App.jsx change. But the issue is nothing in App.jsx will change when you login, so useEffect will not run and the screen cannot change from LoginScreen to HomeScreen.

    I suggest you to use redux and react-redux to create a global state expired and change its value.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search