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

Expo+NativeBase开发 函数组件用Hooks加载Roboto_medium字体报错求解

函数组件下加载NativeBase依赖字体的正确实现

你之前两种写法的失败原因

  • 直接把useEffect回调设为async函数的写法本质无效:useEffect本身同步执行,遇到async函数会立刻拿到一个未完成的Promise,根本不会等字体加载完成就触发首次渲染,此时NativeBase组件找不到已加载的Roboto_medium字体,自然会抛出报错。
  • 在useEffect里写立即执行异步函数的常见疏漏:很多人写完Font.loadAsync的逻辑就结束了,没有严格绑定「字体加载完成前不渲染正式页面」的逻辑,要么过早关闭占位加载页,要么状态更新时序错配,导致字体还在加载中页面就已经渲染了依赖字体的NativeBase组件。

核心判断逻辑:无论采用哪种代码写法,只要字体加载完成的Promise还没resolve,就绝对不能渲染依赖NativeBase字体的正式页面,否则必然触发字体未加载的报错。

标准实现步骤

  1. 引入对应依赖:expo-font的字体加载接口、expo-app-loading的占位加载组件、NativeBase要求的全部字体资源。
  2. 用状态变量跟踪字体加载进度,初始状态设为“未加载完成”。
  3. 在useEffect中执行一次性的字体加载逻辑:不要把useEffect的回调直接写成async,而是在回调内部定义独立的异步加载函数,等Font.loadAsync全部执行完成后,再把字体加载状态更新为“已完成”。

    注意:useEffect的依赖数组设为空数组[]即可,保证字体加载逻辑仅在组件首次挂载时执行一次,避免重复加载触发异常。

  4. 做严格的状态分支判断:字体加载完成前统一返回AppLoading占位,不渲染任何包含NativeBase组件的正式内容;等状态更新为加载完成后,再渲染正式的应用页面。

可直接运行的参考代码

import React, { useState, useEffect } from 'react';
import { View } from 'react-native';
import { NativeBaseProvider, Text } from 'native-base';
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
// 导入NativeBase官方要求的字体资源,路径与项目内实际位置匹配即可
import Roboto from 'native-base/Fonts/Roboto.ttf';
import RobotoMedium from 'native-base/Fonts/Roboto_medium.ttf';
import Ionicons from '@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/Ionicons.ttf';

export default function RootApp() {
  const [isFontReady, setIsFontReady] = useState(false);

  useEffect(() => {
    // 内部定义独立的异步加载函数,不直接给useEffect写async回调
    const loadCustomFonts = async () => {
      await Font.loadAsync({
        Roboto: Roboto,
        Roboto_medium: RobotoMedium,
        Ionicons: Ionicons,
      });
      // 字体全部加载完成后更新状态
      setIsFontReady(true);
    };
    loadCustomFonts();
  }, []);

  // 字体未加载完成时,仅展示占位组件,不渲染正式页面
  if (!isFontReady) {
    return <AppLoading />;
  }

  // 字体加载完成后再渲染依赖NativeBase组件的页面
  return (
    <NativeBaseProvider>
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>字体加载完成,NativeBase组件可正常渲染</Text>
      </View>
    </NativeBaseProvider>
  );
}

容易遗漏的细节

  • 不需要重复在多个子组件里写字体加载逻辑:把整套字体加载逻辑放在应用最根组件的位置,根组件完成字体加载后,所有下层子组件使用NativeBase的字体配置都会正常生效。
  • 加载字体时不要漏写资源条目:必须把NativeBase运行需要的Roboto、Roboto_medium、配套图标字体全部传入Font.loadAsync,少加载任意一个都会触发对应的字体缺失报错。
  • 如果使用NativeBase v3及以上版本,也可以调用官方提供的useFontsHooks简化书写,底层实现逻辑和上述手动管理状态的流程完全一致,不需要手动维护加载状态和占位逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 17:24:05