0

Context: I'm trying to do the authentication of the users when they sing-in getting the token from the backend and storing them in SecureStore to later depending in if it is stored the token navigates to the profile screen or to the register and login screen. In react-native:

The code to access to the register or profile screen depending in if it has the token stored or not:

const MusicScreen = () => {

    //Constante de navegación
    const navigation = useNavigation();
    //Estado para sacar el token de asyncStorage
    const [token, setToken] = useState(null);
    //Saca el token y lo almacena temporalmente en setToken

        const getToken = async () => {
          try {
            const storedToken = await SecureStore.getItemAsync('token');
            setToken(storedToken);
            console.log(storedToken)
          } catch (error) {
            console.error('Error al obtener el token:', error);
          }
        };
    

    const handleIconPress = () => {
        getToken();
        if (token === null) {
          navigation.navigate('Register');
        } else {
          navigation.navigate('Profile');
        }
      };


    return (
        <View >
            <LinearGradient 
            colors={['#c501e2','#fe0ab7','#ae3dff','transparent']} style={styles.Background}>
            <TouchableOpacity onPress={handleIconPress} style={styles.touchable}>
                <Image source={require('../files-logos/D-Corchea.png')} style={styles.image}/>
            </TouchableOpacity>
      </LinearGradient>
        </View>     
  )};

Then, the code to logout on the Profile Screen:

const logout = async() => {
    try{
        await SecureStore.deleteItemAsync('token');
        const storedToken = await SecureStore.getItemAsync('token');
        console.log(storedToken);
    }catch(e){
        console.log('Error trying to delete de token:', e);
    }
}
const ProfileScreen= () => {
    const navigation = useNavigation();
    return (
        <View>
            <Background1/>
        <Text style={{fontWeight:'bold',}}>THis is the profile screen</Text>
        <Button title='logout' onPress={()=>{
            logout();
            navigation.navigate('Register');
        }} />
        </View>
    )};

export default ProfileScreen;

The problem it's that it does not work entirely properly, because it update the value in SecureStore correctly but it navigates properly the second time you click-it.

I've tried the useEffect, but the useEffect is use to update the value when it renders de component, no when it clicks them.

sportfilm
  • 1
  • 1
  • The problem is basically this: `setToken(newToken); console.log(token); //oldToken is displayed` See https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately – James Aug 05 '23 at 18:39
  • @James Thanks for give me the key of the problem – sportfilm Aug 06 '23 at 22:39

1 Answers1

0

After one day thinking on how to solve the issue and what options I have, finally I found the correct way. The main problem it's that useState it doesn't update the values instantly, the common solution it is using useEffect, the problem it's that I want to update the value every time I press the buttom, but the useEffects it acts when it renders the component.

The solution is to create an external function that returns the value from SecureStore, then, in the function of the onpress, it save the value in constant. This works to me, here is the code:

const getToken = async() =>{
          try {
             const storedToken = await SecureStore.getItemAsync('token');
             return storedToken;
          } catch (error) {
            console.error('Error al obtener el token:', error);
            return null;
          }
        };

const MusicScreen = () => {

    //Constante de navegación
    const navigation = useNavigation();
    //Saca el token y lo almacena temporalmente en setToken

    const handleIconPress = async () => {
        const storedToken = await getToken();
        console.log(storedToken)
        if (storedToken === null) {
          navigation.navigate('Register');
        } else {
          navigation.navigate('Profile');
        }
      };


    return (
        <View >
            <LinearGradient 
            colors={['#c501e2','#fe0ab7','#ae3dff','transparent']} style={styles.Background}>
            <TouchableOpacity onPress={handleIconPress} style={styles.touchable}>
                <Image source={require('../files-logos/D-Corchea.png')} style={styles.image}/>
            </TouchableOpacity>
      </LinearGradient>
        </View>     
  )};
sportfilm
  • 1
  • 1