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

React Native Expo中Font.loadAsync未完成组件已用字体问题

解决Expo预加载字体后仍提示「You need to wait for Font.loadAsync to complete before using the font」的问题

你的代码存在逻辑错误,导致自定义字体未被正确预加载:

  • cacheFonts函数的作用是接收字体配置对象,为每个配置调用Font.loadAsync生成加载Promise。但你在传参时,对自定义字体提前调用了Font.loadAsync(...),把返回的Promise传给了cacheFonts,导致cacheFonts内部会对这个Promise再次调用Font.loadAsync,完全偏离预期逻辑。自定义字体实际未加载完成,Promise.all就已执行完毕并设置mainScreenIsReady,最终组件渲染时字体还没加载好,触发报错。

修正步骤

  1. 直接传入字体配置对象到cacheFonts,不要提前调用Font.loadAsync
  2. 确保所有传入cacheFonts的元素都是标准字体配置对象(比如Entypo.font就是符合要求的格式)

修正后的完整代码

import React, { useEffect, useState } from "react";
import { Text, View } from "react-native";
import * as Font from "expo-font";
import Entypo from "@expo/vector-icons/Entypo";

function cacheImages(images) {
    return images.map((image) => {
        if (typeof image === "string") {
            return Image.prefetch(image);
        } else {
            return Asset.fromModule(image).downloadAsync();
        }
    });
}

function cacheFonts(fonts) {
    return fonts.map((font) => Font.loadAsync(font));
}

export default function MainScreen() {
    const [mainScreenIsReady, setMainScreenIsReady] = useState(false);

    useEffect(() => {
        async function loadResourcesAndDataAsync() {
            try {
                const imageAssets = cacheImages([]);

                // 修正:直接传入字体配置对象,而非提前调用Font.loadAsync
                const fontAssets = cacheFonts([
                    Entypo.font,
                    {
                        SFProBold: require("../assets/fonts/SF-Pro-Text-Bold.otf"),
                    },
                ]);

                await Promise.all([...imageAssets, ...fontAssets]);
            } catch (e) {
                console.warn(e);
            } finally {
                setMainScreenIsReady(true);
            }
        }

        loadResourcesAndDataAsync();
    }, []);

    return (
        <>
            {mainScreenIsReady && (
                <View
                    style={{ flex: 1, alignItems: "center", justifyContent: "center" }}
                >
                    <Text style={{ fontFamily: "SFProBold" }}>SplashScreen Demo! 👋</Text>
                    <Entypo name="rocket" size={30} />
                </View>
            )}
        </>
    );
}

修正后,cacheFonts会分别对Entypo.font和自定义字体配置调用Font.loadAsync,生成正确的加载Promise数组。Promise.all会等待所有字体加载完成后再设置mainScreenIsReady,此时组件渲染时字体已加载完毕,不会再出现报错。

内容的提问来源于stack exchange,提问作者ColstonBod-oy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:47:29