如何在 React Native SVG 中正确使用自定义字体

react native svg 的 `` 组件原生不支持自定义字体(截至 v13.4.0),需通过 `` 包裹标准 rn `` 并动态设置 `key` 属性来实现渲染与更新。

在 React Native 项目中,使用 Expo 的 useFonts 成功加载自定义字体(如 'Robo Numbers')后,常规的 react-native 或 react-native-paper 的 组件可正常应用 fontFamily 样式。但 react-native-svg 的 组件并不继承 RN 的字体注册机制——它底层依赖原生 SVG 渲染逻辑,无法识别通过 expo-font 注册的字体名,因此即使显式声明 fontFamily="Robo Numbers",也会回退到系统默认字体。

官方文档与源码均未提供对自定义字体的直接支持方案,社区也普遍确认该功能当前缺失(v13.x 系列)。所幸, 提供了一种稳定、轻量的绕过方案:它允许在 SVG 坐标系中嵌入标准 React Native 元素,从而复用已加载的字体资源。

✅ 正确实现方式如下:

import { ForeignObject, Text as SvgText } from 'react-native-svg';
import { Text } from 'react-native';

// 假设已在组件顶层调用 useFonts({...})
const CountdownDisplay = ({ countdown }: { countdown: number }) => {
  return (
    
       10 ? '#f8f0c1' : 'orange'
      }}>
        {countdown}
      
    
  );
};

⚠️ 关键注意事项:

  • ForeignObject 必须设置 动态 key 属性(如 key={countdown}),否则其子元素不会随状态更新而重渲染 —— 这是常见陷阱,尤其在定时器(如 setInterval)驱动的数字变化场景中;
  • x/y 定义 SVG 内部坐标原点,width/height 应合理覆盖文本区域,避免截断;
  • ForeignObject 在 Android 和 iOS 上兼容性良好,但不支持 Web 端(若需多端一致,请结合平台判断或降级处理);
  • 避免嵌套过深或高频重绘大量 ForeignObject,可能影响性能。

? 补充建议:若项目重度依赖 SVG 文本样式,可考虑将数字文本预渲染为 (通过字体转 SVG 轮廓工具离线生成),但开发成本显著升高;对于大多数动态场景,ForeignObject + key 是当前最实用、可维护的解决方案。