React native дождитесь, пока пользователь войдет в систему, прежде чем переходить по экранам - PullRequest
2 голосов
/ 06 августа 2020

У меня есть функция, которая извлекает токен из SecureStore в response-native

export const isUserLoggedIn = async () =>{
  return await SecureStore.getItemAsync('jwtToken') ? true : false
}

Это мой навигатор:

function RootNavigator() {
  const [isLoggedIn, setIsLoggedIn] = useState(false)

  console.log("isUserLoggedIn()", isUserLoggedIn());
  (async () => {
    const someBoolean =  await isUserLoggedIn()
    console.log("inside then")
    setIsLoggedIn(someBoolean)

    return (
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        {isLoggedIn || <Stack.Screen name="Root" component={WelcomeScreen} />}
        {isLoggedIn && <Stack.Screen name="InvestorProfileQuiz" component={InvestorProfileQuizScreen} />}
        {isLoggedIn || <Stack.Screen name="AppTour" component={AppTourScreen} />}
        {isLoggedIn || <Stack.Screen name="Login" component={LoginScreen} />}
        {isLoggedIn || <Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} />}
      </Stack.Navigator>
    );
  })()
  console.log("LOGGED IN STATE:", isLoggedIn)

Проблема в том, что LOGGED_IN_STATE регистрируется перед inside then console.log, что означает, что код не блокируется и не ожидает разрешения isUserLoggedIn(). isUserLoggedIn() возвращает обещание, потому что это функция asyn c await, но нужно ли мне ждать его разрешения перед рендерингом Stack Navigator? Короче говоря, я хочу, чтобы вошедший в систему пользователь имел доступ к определенным экранам, а не к другим. Что я делаю не так?

1 Ответ

1 голос
/ 06 августа 2020

Я обычно обрабатываю состояние входа в систему примерно так:

function RootNavigator() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);

  // Passing an empty array as second argument
  // makes useEffect behave like componentDidMount
  useEffect(() => {
    
    // Wrap logic in the async init function
    // since the useEffect callback can't be async
    async function init() {
      const someBoolean = await isUserLoggedIn();
      setIsLoggedIn(someBoolean);
    }
    init();
  }, []);

  // Return null or your logged out screen component here.
  if (!isLoggedIn) {
    return null;
  }

  return (
    <Stack.Navigator screenOptions={{headerShown: false}}>
      <Stack.Screen name="Root" component={WelcomeScreen} />}
      <Stack.Screen
        name="InvestorProfileQuiz"
        component={InvestorProfileQuizScreen}
      />
      <Stack.Screen name="AppTour" component={AppTourScreen} />
      <Stack.Screen name="Login" component={LoginScreen} />(
      <Stack.Screen
        name="NotFound"
        component={NotFoundScreen}
        options={{title: 'Oops!'}}
      />
    </Stack.Navigator>
  );
}

В вашем коде console.log("LOGGED IN STATE:", isLoggedIn) не ждет, потому что asyn c await инкапсулирован в IIFE (https://developer.mozilla.org/en-US/docs/Glossary/IIFE) объем функции.

...