使用useFonts加载字体后,useCallback无法检测并隐藏SplashScreen
Expo React Native:自定义字体加载后启动屏无法隐藏的解决方案
核心问题分析
- useCallback理解偏差:useCallback的作用是缓存函数引用,并非监听状态变化触发执行——你把它当成useEffect来用了,导致定义好的
onLayoutRootView从未被调用。 - 启动屏隐藏逻辑未触发:即便写了隐藏启动屏的代码,也没有在合适时机执行它。
- 拼写不规范:
expo-splash-screen官方导出的是首字母大写的SplashScreen,你代码里写成了Splashscreen,虽可能不报错,但需修正以符合规范。 - 加载指示器逻辑错误:
ActivityIndicator的animating属性值写反了,应该在字体未加载完成时显示动画。
修正后的代码
import { useFonts } from "expo-font"; import { useEffect } from "react"; import * as SplashScreen from "expo-splash-screen"; import { NavigationContainer } from "@react-navigation/native"; import { createStackNavigator } from "@react-navigation/stack"; import { Onboarding } from "./screens"; import { ActivityIndicator, View, StyleSheet } from "react-native"; // 阻止启动屏自动隐藏 SplashScreen.preventAutoHideAsync(); const Stack = createStackNavigator(); export default function App() { const [fontsLoaded, fontError] = useFonts({ fo_regular: require("./assets/fonts/regular.otf"), fo_bold: require("./assets/fonts/bold.otf"), fo_medium: require("./assets/fonts/medium.otf"), fo_light: require("./assets/fonts/light.otf"), fo_xtrabold: require("./assets/fonts/xtrabold.otf"), }); // 用useEffect监听字体加载状态,满足条件后隐藏启动屏 useEffect(() => { async function hideSplashScreen() { if (fontsLoaded || fontError) { await SplashScreen.hideAsync(); } } hideSplashScreen(); }, [fontsLoaded, fontError]); // 字体未加载完成且无错误时,显示居中的加载指示器 if (!fontsLoaded && !fontError) { return ( <View style={styles.container}> <ActivityIndicator size="small" color="black" animating={true} /> </View> ); } return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Onboard" component={Onboarding} options={{ headerShown: false }} /> </Stack.Navigator> </NavigationContainer> ); } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: "center", alignItems: "center", }, });
关键修改说明
- 替换useCallback为useEffect:useEffect专门处理状态变化后的副作用操作,这里监听
fontsLoaded和fontError的变化,一旦字体加载完成或出现错误,自动触发启动屏隐藏逻辑。 - 统一SplashScreen拼写:修正为官方规范的首字母大写形式,避免潜在兼容性问题。
- 优化加载指示器布局:添加全屏容器让指示器居中显示,同时将
animating设为true,符合加载中的状态逻辑。 - 自动触发隐藏逻辑:通过useEffect无需手动调用函数,确保状态变化时自动执行启动屏隐藏操作。
针对真机卡顿的额外建议
- 压缩字体文件大小,移除不必要的字重或字符集;
- 升级到最新版本的Expo SDK,修复旧版本中启动屏与字体加载的兼容性问题;
- 真机测试时关闭远程JS调试模式,减少性能损耗。
内容的提问来源于stack exchange,提问作者code46
相关产品推荐
相关产品推荐

