React Native添加自定义字体失败,求解决方案
问题分析与解决方案
看起来你遇到的核心问题是没有等待字体加载完成就渲染了使用该字体的组件,同时还混用了两种冲突的React Native字体加载方式(Expo的Font.loadAsync和传统的react-native link),这双重因素导致了报错。
问题拆解
你用了Expo的Font.loadAsync加载自定义字体,但组件渲染时字体可能还没加载完成——loadFont是异步函数,useEffect里调用它却没等待完成就直接渲染<Text>,此时字体未准备好就会触发报错。另外,Expo项目不需要通过react-native link或package.json的rnpm配置加载字体,这两种方式会和Expo的资源管理逻辑冲突。
具体修复步骤
1. 移除冲突配置
先删除package.json里的rnpm配置块,也不用再执行react-native link命令,Expo会自行处理资源打包。
2. 添加字体加载状态跟踪
在组件里新增状态跟踪字体是否加载完成,只有加载完成后再渲染使用自定义字体的内容,否则显示加载提示。
修改后的App.js代码如下:
import React, { useEffect, useState } from 'react'; import { StyleSheet, Text, View, Image, ActivityIndicator } from 'react-native'; import imager from './assets/cars.png'; import * as Font from 'expo-font'; export default function App() { // 新增加载状态 const [fontsLoaded, setFontsLoaded] = useState(false); useEffect(() => { async function loadFont() { try { await Font.loadAsync({ righteous: require('./assets/fonts/Righteous-Regular.ttf'), }); // 加载完成后更新状态 setFontsLoaded(true); } catch (error) { console.error('字体加载失败:', error); } } loadFont(); }, []); // 字体未加载完成时显示加载指示器 if (!fontsLoaded) { return ( <View style={styles.container}> <ActivityIndicator size="large" color="#0000ff" /> </View> ); } // 字体加载完成后渲染核心内容 return ( <View style={styles.container}> <Image style={styles.imager} source={imager} /> <Text style={{ fontSize: 30, fontWeight: 'bold', paddingTop: 30, fontFamily: 'righteous', // 需与loadAsync里的key完全一致 }} > Request Ride </Text> <Text style={{ fontSize: 15, padding: 40, textAlign: 'center' }}> Request a ride and get picked up by a nearby community driver </Text> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center', }, imager: { width: 200, height: 200, shadowColor: 'rgba(0, 0, 0, 0.2)', shadowRadius: 10, shadowOpacity: 1, }, });
3. 额外排查点
- 确认字体文件路径和拼写(包括大小写)完全正确:
./assets/fonts/Righteous-Regular.ttf确实存在。 - 重启Expo开发服务器:执行
expo start --clear清除缓存后启动,避免资源缓存导致的问题。 - 检查
Font.loadAsync的key(这里是righteous)与<Text>的fontFamily值完全匹配,大小写也要一致。
为什么之前的方法无效?
传统的react-native link是针对裸React Native项目的,而Expo有自己的资源加载机制,通过expo-font管理字体,混用两种方式会导致Expo无法正确识别加载的字体。另外,异步加载字体时必须等待完成再渲染使用该字体的组件,否则组件会尝试调用未加载的字体,从而抛出错误。
内容的提问来源于stack exchange,提问作者codebarz
相关产品推荐
相关产品推荐

