From d0ddf649c59f4b21a96a2d64fb68d6e4a40dc2ba Mon Sep 17 00:00:00 2001 From: songyipan <3515164447@qq.com> Date: Fri, 24 Apr 2026 23:17:12 +0800 Subject: [PATCH] fix: hide splash screen on onboarding and login screens SplashScreen was only hidden in TabLayout, but when isFirstTime is true or user is signed out, the app redirects to onboarding/login screens before TabLayout's useEffect runs, causing the splash screen to never hide. Also added error handling to storage getItem to prevent JSON.parse exceptions from blocking auth hydration. Co-Authored-By: Claude Opus 4.6 --- src/features/auth/login-screen.tsx | 5 +++++ src/features/onboarding/onboarding-screen.tsx | 6 ++++++ src/lib/storage.tsx | 12 ++++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/features/auth/login-screen.tsx b/src/features/auth/login-screen.tsx index 42c5b89c7..4cf5305b9 100644 --- a/src/features/auth/login-screen.tsx +++ b/src/features/auth/login-screen.tsx @@ -1,5 +1,6 @@ import type { LoginFormProps } from './components/login-form'; import { useRouter } from 'expo-router'; +import * as SplashScreen from 'expo-splash-screen'; import * as React from 'react'; import { FocusAwareStatusBar } from '@/components/ui'; @@ -10,6 +11,10 @@ export function LoginScreen() { const router = useRouter(); const signIn = useAuthStore.use.signIn(); + React.useEffect(() => { + SplashScreen.hideAsync(); + }, []); + const onSubmit: LoginFormProps['onSubmit'] = (data) => { console.log(data); signIn({ access: 'access-token', refresh: 'refresh-token' }); diff --git a/src/features/onboarding/onboarding-screen.tsx b/src/features/onboarding/onboarding-screen.tsx index 6d1655075..90e8a66d3 100644 --- a/src/features/onboarding/onboarding-screen.tsx +++ b/src/features/onboarding/onboarding-screen.tsx @@ -1,4 +1,5 @@ import { useRouter } from 'expo-router'; +import * as SplashScreen from 'expo-splash-screen'; import * as React from 'react'; import { @@ -14,6 +15,11 @@ import { Cover } from './components/cover'; export function OnboardingScreen() { const [_, setIsFirstTime] = useIsFirstTime(); const router = useRouter(); + + React.useEffect(() => { + SplashScreen.hideAsync(); + }, []); + return ( diff --git a/src/lib/storage.tsx b/src/lib/storage.tsx index 8c0422609..4b049d673 100644 --- a/src/lib/storage.tsx +++ b/src/lib/storage.tsx @@ -3,8 +3,16 @@ import { createMMKV } from 'react-native-mmkv'; export const storage = createMMKV(); export function getItem(key: string): T | null { - const value = storage.getString(key); - return value ? JSON.parse(value) || null : null; + try { + const value = storage.getString(key); + if (!value) + return null; + return JSON.parse(value) ?? null; + } + catch (e) { + console.error(`Failed to get item "${key}":`, e); + return null; + } } export async function setItem(key: string, value: T) {