为什么我的 Expo onboardScreen 无法正常工作

问题描述 投票:0回答:1

当我在新安装后打开应用程序时,它首先显示主页,然后突然更改为板载屏幕。当我打开应用程序时,它不会直接进入板载屏幕。为什么会发生这种情况? 我需要显示板载屏幕,但它无法正常工作。首先它显示主屏幕一秒钟,然后导航到板载屏幕。 如果有人知道请帮忙。 enter image description here

enter image description here

import FontAwesome from "@expo/vector-icons/FontAwesome";
import { useFonts } from "expo-font";
import { Stack, useRouter } from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { useEffect, useState } from "react";
import "react-native-reanimated";
import Providers from "@/redux/provider";
import AsyncStorage from "@react-native-async-storage/async-storage";

export {
  ErrorBoundary,
} from "expo-router";

export const unstable_settings = {
  initialRouteName: "/",
};

SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  const [loaded, error] = useFonts({
    SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
    ...FontAwesome.font,
  });

  const [onBoardingChecked, setOnBoardingChecked] = useState(false);
  const [initialRoute, setInitialRoute] = useState("/(onboard)/onboard");
  const router = useRouter();

  useEffect(() => {
    const checkOnboardingStatus = async () => {
      try {
        const onBoardSeenData = await AsyncStorage.getItem("inkwellAppData");
        const parsedData =
          onBoardSeenData !== null ? JSON.parse(onBoardSeenData) : null;
        const onboardSeenStatus =
          parsedData !== null ? parsedData?.onboardSeen : null;
        console.log(onboardSeenStatus);

        if (!onboardSeenStatus) {
          console.log("first");
          setInitialRoute("/(onboard)/onboard");
        } else {
          console.log("second");
          setInitialRoute("/");
        }
      } catch (error) {
        console.error("Failed to load onboarding status:", error);
      } finally {
        setOnBoardingChecked(true);
      }
    };

    checkOnboardingStatus();
  }, []);

  useEffect(() => {
    if (error) throw error;
  }, [error]);

  useEffect(() => {
    if (loaded && onBoardingChecked) {
      router.replace(initialRoute);
      SplashScreen.hideAsync();
    }
  }, [loaded, onBoardingChecked, initialRoute]);

  if (!loaded || !onBoardingChecked) {
    return null;
  }
  return <RootLayoutNav />;
}

function RootLayoutNav() {
  return (
    <Providers>
        <Stack screenOptions={{headerShown:false}}>
          <Stack.Screen name="(app)" options={{ headerShown: false }} />
        </Stack>
    </Providers>
  );
}
android ios react-native
1个回答
0
投票

应用程序启动时,首先显示主屏幕,因为它会单独检查登录状态,并在检查完成后才设置初始路线。这是要做的事情:

  • 保持初始屏幕可见,直到完成入职检查。
  • 根据登机状态设置初始路线。

这里我对代码进行了更改以正确处理这些情况:

import FontAwesome from "@expo/vector-icons/FontAwesome";
import { useFonts } from "expo-font";
import { Stack, useRouter } from "expo-router";
import * as SplashScreen from "expo-splash-screen";
import { useEffect, useState } from "react";
import "react-native-reanimated";
import Providers from "@/redux/provider";
import AsyncStorage from "@react-native-async-storage/async-storage";

export { ErrorBoundary } from "expo-router";

export const unstable_settings = {
  initialRouteName: null, // Set to null to handle initial route dynamically
};

SplashScreen.preventAutoHideAsync();

export default function RootLayout() {
  const [loaded, error] = useFonts({
    SpaceMono: require("../assets/fonts/SpaceMono-Regular.ttf"),
    ...FontAwesome.font,
  });

  const [onBoardingChecked, setOnBoardingChecked] = useState(false);
  const router = useRouter();

  useEffect(() => {
    const checkOnboardingStatus = async () => {
      try {
        const onBoardSeenData = await AsyncStorage.getItem("inkwellAppData");
        const parsedData = onBoardSeenData !== null ? JSON.parse(onBoardSeenData) : null;
        const onboardSeenStatus = parsedData !== null ? parsedData?.onboardSeen : null;

        if (!onboardSeenStatus) {
          setInitialRoute("/(onboard)/onboard");
        } else {
          setInitialRoute("/");
        }
      } catch (error) {
        console.error("Failed to load onboarding status:", error);
      } finally {
        setOnBoardingChecked(true);
      }
    };

    checkOnboardingStatus();
  }, []);

  useEffect(() => {
    if (error) throw error;
  }, [error]);

  useEffect(() => {
    if (loaded && onBoardingChecked) {
      router.replace(initialRoute);
      SplashScreen.hideAsync();
    }
  }, [loaded, onBoardingChecked]);

  if (!loaded || !onBoardingChecked) {
    return null;
  }

  return <RootLayoutNav />;
}

function RootLayoutNav() {
  return (
    <Providers>
      <Stack screenOptions={{ headerShown: false }}>
        <Stack.Screen name="(app)" options={{ headerShown: false }} />
        <Stack.Screen name="(onboard)" options={{ headerShown: false }} />
      </Stack>
    </Providers>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.