You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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",
  },
});

关键修改说明

  1. 替换useCallback为useEffect:useEffect专门处理状态变化后的副作用操作,这里监听fontsLoaded和fontError的变化,一旦字体加载完成或出现错误,自动触发启动屏隐藏逻辑。
  2. 统一SplashScreen拼写:修正为官方规范的首字母大写形式,避免潜在兼容性问题。
  3. 优化加载指示器布局:添加全屏容器让指示器居中显示,同时将animating设为true,符合加载中的状态逻辑。
  4. 自动触发隐藏逻辑:通过useEffect无需手动调用函数,确保状态变化时自动执行启动屏隐藏操作。

针对真机卡顿的额外建议

  • 压缩字体文件大小,移除不必要的字重或字符集;
  • 升级到最新版本的Expo SDK,修复旧版本中启动屏与字体加载的兼容性问题;
  • 真机测试时关闭远程JS调试模式,减少性能损耗。

内容的提问来源于stack exchange,提问作者code46

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:03:39