Выход из системы при каждом обновлении приложения React Native Expo?

#react-native #expo #asyncstorage

#react-native #выставка #asyncstorage

Вопрос:

Я новичок в React Native и использую Expo и пытаюсь войти в систему с помощью AuthContext и AsyncStorage, после входа в систему я попадаю на рабочий стол. Но когда я вношу изменения в компоненты, это обновляет приложение и выводит меня из приложения. И каждый раз, когда я вношу некоторые изменения, мне нужно снова войти в систему.

Кто-нибудь может мне помочь, где я ошибаюсь. Сейчас я использую AsyncStorage для автономной поддержки и редукторов.

App.js

 <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        { loginState.userToken != null ? (
          <Drawer.Navigator>
            <Drawer.Screen name="Home" component={PreNav}/>
            <Drawer.Screen name="Support" component={SupportScreen}/>
            <Drawer.Screen name="Settings" component={SettingsScreen}></Drawer.Screen>
          </Drawer.Navigator>
        ): <RootStackScreen />
        }
      </NavigationContainer>
    </AuthContext.Provider>

const initialLoginState = {
    isLoading: true,
    userName: null,
    userToken: null,
  }

  const loginReducer = (prevState, action) => {
    switch(action.type) {
      case 'RETRIEVE_TOKEN':
        return {
          ...prevState,
          userToken: action.token,
          isLoading: false
        };
      case 'LOGIN':
        return {
          ...prevState,
          userName: action.id,
          userToken: action.token,
          isLoading: false
        };
      case 'LOGOUT':
        return {
          ...prevState,
          userName: null,
          userToken: null,
          isLoading: false
        };
      case 'REGISTER':
        return {
          ...prevState,
          userName: action.id,
          userToken: action.token,
          isLoading: false
        }; 
    }
  }

  const [loginState, dispatch] = useReducer(loginReducer, initialLoginState)

  const authContext = useMemo(() => ({
    userLogin: async (userName, password) => {
      // setUserToken("abc");
      // setLoading(false);
      let userToken;
      userToken = 'abc';
      if (userName == 'user' amp;amp; password == 'pass') {
        try {
          await AsyncStorage.setItem('userToken', userToken)
        }
        catch(e) {
          console.log(e);
        }
      }
      dispatch({type: 'LOGIN', id: userName, token: userToken});

    },

    userSignup: () => {
      
    },
  }));

  useEffect(() => {
    setTimeout(async () => {
      // setLoading(false);
      let userToken;
      try {
        await AsyncStorage.getItem('userToken')
      }
      catch(e) {
        console.log(e);
      }
      dispatch({type: 'RETRIEVE_TOKEN', token: userToken});
    }, 1000);
  }, []);

 

LoginScreen.js

 const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");
    const [pwd, resetPwd] = useState(false);

    const { userLogin } = useContext(AuthContext);

    return(
        <KeyboardAvoidingView behavior='position'>
            <View style={styles.logoView}>
                <Image style={styles.loginImage} source={require('../assets/login.png')}/>
                <View>
                    <Text style={styles.logoText}> Welcome </Text>
                    <Text style={styles.logoSubText}> Please Login to continue, If account already created. </Text>
                </View>
            </View>


            <View style={styles.loginInput}>
                <Input placeholder='Enter your email address' value={email} onChangeText={(email) => setEmail(email)}
                    leftIcon={<IconI name='email' size={24} color='black' />}/>
                <Input placeholder='Enter your password' secureTextEntry={true} value={password} onChangeText={(password) => {setPassword(password)}}
                    leftIcon={<Icon name='key' size={24} color='black' />}/>
            </View>

            <View style={styles.loginButtonBox}>
                <TouchableOpacity onPress={() => userLogin(email, password)}>
                    <Text style={styles.loginButton}> LOGIN </Text>
                </TouchableOpacity>
            </View>
            
            <View style={styles.noAccount}>
                <Text>{"n"} Don't have an account yet ? </Text>
                <TouchableOpacity onPress={() => navigation.navigate('SignupScreen')}>
                  <Text style={styles.linkText}>{"n"} Create New One </Text>
                </TouchableOpacity>
            </View>
            
            <View style={styles.forgotPassword}>
                <Text>{"n"} Don't remember the Password ? </Text>
                <TouchableOpacity style={styles.linkText} onPress={() => {
                    resetPwd(true);
                }}>
                    <Text style={styles.linkText}>{"n"} Forgot Password </Text>
                </TouchableOpacity>
            </View>
 

context.js

 export const AuthContext = createContext();
 

Ответ №1:

Согласно наблюдению за предоставленным вами кодом,

вот проблема, возникающая из-за того, что сохранение UserToken с помощью действия RETRIVE_TOKEN не работает должным образом, поскольку поведение кода не инициализировало переменную UserToken значением, которое она получает из асинхронного хранилища, поэтому вам необходимо инициализировать переменную UserToken значением, полученным из AsyncStorage.

вы можете попробовать внести следующие изменения в свой код App.js Крючок useEffect

   useEffect(() => {
    setTimeout(async () => {
      let userToken;
      try {
        userToken = await AsyncStorage.getItem('userToken')
      }
      catch(e) {
        console.log(e);
      }
      dispatch({type: 'RETRIEVE_TOKEN', token: userToken});
    }, 1000);
  }, []);
 

Комментарии:

1. Вау! такая глупая ошибка от меня. Спасибо!