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

React Native 不使用Expo实现字体加载的方法咨询

无Expo的React Native项目实现异步加载字体方案

前置说明

你示例中使用expo-font实现的是应用启动阶段异步加载本地字体、加载完成后再渲染主内容的效果,纯React Native项目可以根据使用场景选择以下两种实现方案:

方案1:内置固定字体场景(最常用,适配你示例的需求)

如果字体是固定的,提前放到项目中打包到APP包内,不需要额外引入第三方库,操作步骤如下:

  • 第一步:在项目根目录创建assets/fonts文件夹,将所有字体文件放入该目录
  • 第二步:在项目根目录新建react-native.config.js文件,添加如下配置,用于告知React Native字体资源路径:
module.exports = {
  project: {
    ios: {},
    android: {}
  },
  assets: ['./assets/fonts/']
};
  • 第三步:执行命令npx react-native link,0.60及以上版本的React Native会自动将字体资源链接到iOS、Android原生项目中,无需手动修改原生配置。
  • 第四步:编写应用加载逻辑,和你示例的逻辑对齐:
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
// 你可以用第三方启动屏库代替原来的AppLoading组件,也可以自定义加载页
import SplashScreen from 'react-native-splash-screen';

export default class App extends React.Component {
  state = {
    isFontLoaded: false
  }

  async componentDidMount() {
    // 内置字体已经在原生层完成加载,这里可直接做初始化,若需要模拟异步等待也可加延时逻辑
    this.setState({ isFontLoaded: true }, () => {
      SplashScreen.hide(); // 字体加载完成后隐藏启动屏
    })
  }

  render() {
    if (!this.state.isFontLoaded) {
      // 无启动屏库的情况下可以直接返回自定义加载页
      return <View style={styles.loadingPage} />
    }

    return (
      <View style={styles.container}>
        <Text style={{ fontFamily: 'Montserrat-ExtraBold', fontSize: 20 }}>粗体测试文本</Text>
        <Text style={{ fontFamily: 'Montserrat-Medium', fontSize: 20 }}>中粗测试文本</Text>
        <Text style={{ fontFamily: 'Montserrat-Regular', fontSize: 20 }}>常规测试文本</Text>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  loadingPage: {
    flex: 1,
    backgroundColor: '#ffffff'
  },
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center'
  }
})

注意:fontFamily的取值必须和字体的PostScript名称完全一致,iOS会严格校验该名称,和字体文件名无关,你可以用字体查看工具打开字体文件确认对应的PostScript名称

方案2:运行时动态加载字体场景

如果需要在应用运行过程中动态加载字体(比如加载本地未内置的字体、从远程服务器下载字体),可以使用社区维护的react-native-dynamic-fonts库,安装配置完成后,实现逻辑和expo-font完全对齐,示例代码如下:

import React from 'react';
import { View, Text } from 'react-native';
import DynamicFonts from 'react-native-dynamic-fonts';

export default class App extends React.Component {
  state = {
    isFontLoaded: false
  }

  async componentDidMount() {
    await Promise.all([
      DynamicFonts.load('Montserrat-ExtraBold', require('./assets/fonts/Montserrat-ExtraBold.otf')),
      DynamicFonts.load('Montserrat-Medium', require('./assets/fonts/Montserrat-Medium.otf')),
      DynamicFonts.load('Montserrat-Regular', require('./assets/fonts/Montserrat-Regular.otf'))
    ])
    this.setState({ isFontLoaded: true })
  }

  render() {
    if (!this.state.isFontLoaded) {
      return <View style={{ flex: 1, backgroundColor: '#fff' }} />
    }

    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text style={{ fontFamily: 'Montserrat-ExtraBold', fontSize: 22 }}>动态加载字体测试</Text>
      </View>
    )
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 00:36:07