React Native -身份验证-触发器值以更改身份验证和非身份验证堆栈导航器

ehxuflar  于 2022-12-30  发布在  React
关注(0)|答案(2)|浏览(180)

这里是我的App.js

import React, { useEffect } from "react";
import { NavigationContainer } from "@react-navigation/native";

import AuthStore from "./src/stores/AuthStore";
import AuthStackNavigator from "./src/navigation/AuthStackNavigator";
import UnAuthStackNavigator from "./src/navigation/UnAuthStackNavigator";

const App = () => {
  useEffect(() => {
    console.log("APP JS", AuthStore.userAuthenticated);
  }, [AuthStore.userAuthenticated]);

  return <NavigationContainer>
    {AuthStore.userAuthenticated ? <AuthStackNavigator /> : <UnAuthStackNavigator />}
    </NavigationContainer>;
};

export default App;

userAuthenticated的AuthStore值在自动登录或登录时计算和更新。
此处为AuthStore.js

import { userLogin, userRegister } from "../api/AuthAgent";
import { clearStorage, retrieveUserSession, storeUserSession } from "../utils/EncryptedStorage";
import { Alert } from "react-native";
import { computed, makeObservable, observable } from "mobx";
import { setBearerToken } from "../config/HttpClient";

class AuthStore {
  user = {};
  token = undefined;
  refreshToken = undefined;
  decodedToken = undefined;
  
  constructor() {
    makeObservable(this, {
      token: observable,
      refreshToken: observable,
      user: observable,
      decodedToken: observable,
      userAuthenticated: computed,
    });
    this.autoLogin();
  }

  async doLogin(body) {
    const resp = await userLogin(body);
    console.log("AuthStore > userLogin > resp => ", resp);

    if (resp.success) {
      this.decodedToken = await this.getDecodedToken(resp.token);
      this.setUserData(resp);
      storeUserSession(resp);
    } else {
      Alert.alert(
        "Wrong credentials!",
        "Please, make sure that your email & password are correct",
      );
    }
  }

  async autoLogin() {
    const user = await retrieveUserSession();
    if (user) {
      this.setUserData(user);
    }
  }

  setUserData(data) {
    this.user = data;
    this.token = data.token;
    setBearerToken(data.token);
  }

  get userAuthenticated() {
    console.log('AuthStore > MOBX - COMPUTED userAuthenticated', this.user);
    if (this.token) {
      return true;
    } else return false;
  }

  async logout() {
    await clearStorage();
    this.user = undefined;
    this.token = undefined;
    this.refreshToken = undefined;
    this.decodedToken = undefined;
  }

}

export default new AuthStore();

主要问题是AuthStore.userAuthenticated值即使在AuthStore上更改,也不会由App.js的useEffect触发。因此,当我登录或注销时,我必须重新加载应用程序以触发useEffect钩子,然后只更新导航器。

gijlo24d

gijlo24d1#

您可以使用useMemo钩子来实现这一点。

const App = () => {
const [userToken, setUserToken] = useState("")  

const authContext: any = useMemo(() => {
        return {
          signIn: (data: any) => {
            AsyncStorage.setValue("token", data.accessToken);
            setUserToken(data.accessToken);
          },
          signOut: () => {
            setUserToken("");
            AsyncStorage.setValue("token", "");
          },
        };
      }, []);

 return ( 
    <AuthContext.Provider value={authContext}>
              {userToken.length ? (
                <UnAuthStackNavigator />
              ) : (
                <AuthStackNavigator />
              )}
            )
    </AuthContext.Provider>
 )
}

AuthContext.ts

import React from "react";
export const AuthContext: any = React.createContext({
  signIn: (res: any) => {},
  signOut: () => {},
});

现在你可以在任何文件中使用这个函数,如下所示:

export const SignIn = () => {
       const { signIn } = useContext(AuthContext);
           return (
             <Button onPress={() => {signIn()}}  />
           )
    }
disho6za

disho6za2#

如果您的主要目的是在堆栈中导航和导航,无论身份验证是否可用,那么asynstorage是您必须首先存储令牌的最佳选择。

const storeToken = async (value) => {
  try {
    await AsynStorage.setItem("userAuthenticated", JSON.stringify(value));
  } catch (error) {
    console.log(error);
  }
};

(“userAuthenticated”是我们获取值的键)
现在转到您希望此令牌运行车削条件的屏幕

const [token, setToken] = useState();

const getToken = async () => {
  try {
    const userData = JSON.parse(await AsynStorage.getItem("userAuthenticated"))
    setToken(userData)
  } catch (error) {
   console.log(error); 
  }
};

现在使用状态中的令牌,然后运行条件:

{token? <AuthStackNavigator /> : <UnAuthStackNavigator />}
    or 
     {token != null? <AuthStackNavigator /> : <UnAuthStackNavigator />}

相关问题