React Native中Expo SplashScreen搭配Font.loadAsync无法正常工作
解决Expo SDK45中替换AppLoading为SplashScreen后的字体加载问题
你的代码存在几个关键问题,导致启动页一直显示、字体加载不稳定:
核心问题分析
- 字体加载完成后未更新
appIsReady状态,组件一直返回null,启动页无法隐藏 SplashScreen.preventAutoHideAsync()直接在组件外调用,存在异步执行顺序隐患- 根组件未绑定
onLayoutRootView回调,无法触发启动页隐藏逻辑 - 字体未加载完成就可能渲染组件,导致字体报错或加载不稳定
修复后的完整代码
import React, { useState, useEffect, useCallback } from 'react'; import { View, Text } from 'react-native'; import * as Font from "expo-font"; import * as SplashScreen from 'expo-splash-screen'; export default function App() { const [appIsReady, setAppIsReady] = useState(false); useEffect(() => { async function prepare() { try { // 先阻止启动页自动隐藏 await SplashScreen.preventAutoHideAsync(); // 加载自定义字体 await Font.loadAsync({ "open-sans": require("./assets/fonts/OpenSans-Regular.ttf"), "open-sans-bold": require("./assets/fonts/OpenSans-Bold.ttf"), }); } catch (e) { console.warn('字体加载失败:', e); } finally { // 无论加载成功与否,标记应用已准备完成 setAppIsReady(true); } } prepare(); }, []); const onLayoutRootView = useCallback(async () => { if (appIsReady) { // 根组件布局完成后隐藏启动页 await SplashScreen.hideAsync(); } }, [appIsReady]); if (!appIsReady) { return null; } // 必须将onLayout绑定到根组件上 return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} onLayout={onLayoutRootView}> <Text style={{ fontFamily: 'open-sans' }}>普通OpenSans字体</Text> <Text style={{ fontFamily: 'open-sans-bold', marginTop: 10 }}>加粗OpenSans字体</Text> </View> ); }
关键修复点说明
- 将
SplashScreen.preventAutoHideAsync()移到useEffect的prepare函数内,确保字体加载前先锁定启动页 - 在
finally块中设置setAppIsReady(true),保证无论字体加载是否成功,应用都能继续运行 - 根组件必须添加
onLayout={onLayoutRootView},触发启动页隐藏的时机是组件布局完成后,避免出现空白屏 - 只有当
appIsReady为true时才渲染内容,确保字体加载完成后再显示使用自定义字体的组件
额外注意事项
- 确认字体文件路径正确,
./assets/fonts/下确实存在对应的.ttf文件 - 若仍有字体报错,可尝试清除Expo缓存:运行
expo r -c重启项目 - 测试时使用真机或最新版本的Expo Go,避免旧版本兼容性问题
内容的提问来源于stack exchange,提问作者Twos22
相关产品推荐
相关产品推荐

