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

React Native映射SVG对象遇循环结构序列化错误如何解决?

React Native 替换PNG为SVG后循环结构序列化错误的解决方法

原PNG实现代码

导入图片

import { alergology, cardiology, dermatology, endocrinology, gynecology } from '@/constants/images'

创建映射对象

const images: IObjectKeys = {
  Alergología: alergology,
  Cardiología: cardiology,
  Dermatología: dermatology,
  Endocrinología: endocrinology,
  Ginecología: gynecology,
};

为专业数据添加图片的方法

export const addingImgToSpecialties = (specialties: Speciality[]) =>
  specialties.map((specialty) => {
    const { name } = specialty;
    return {
      ...specialty,
      img: images[name],
    };
  });

替换SVG后的问题

已安装react-native-svg并在其他视图正常使用,尝试导入SVG并创建映射:

import Alergology from '@assets/images/specialties/alergologia.svg';
import Cardiology from '@assets/images/specialties/cardiologia.svg';
import Dermatology from '@assets/images/specialties/dermatologia.svg';
import Endocrinology from '@assets/images/specialties/endocrinologia.svg';
import Gynecology from '@assets/images/specialties/ginecologia.svg';
const images: IObjectKeys = {
  Alergología: Alergology,
  Cardiología: Cardiology,
  Dermatología: Dermatology,
  Endocrinología: Endocrinology,
  Ginecología: Gynecology,
};

应用崩溃,报错:

[Unhandled promise rejection: TypeError: JSON.stringify cannot serialize cyclic structures.]

解决方案

问题根源是:PNG导入后是静态资源路径/对象,可被JSON序列化;但SVG在React Native中是React组件对象,组件内部存在循环引用结构,无法被JSON.stringify序列化(比如处理后的specialties数据存入状态管理、或通过异步传递时会触发序列化)。

调整方案如下:

方案1:分离组件映射与业务数据(推荐)

不要将SVG组件直接挂载到业务数据对象中,而是存储组件的标识,在渲染时根据标识匹配对应的SVG组件。

  1. 单独维护SVG组件映射,处理数据时保留专业名称作为标识
// 导入SVG组件
import Alergology from '@assets/images/specialties/alergologia.svg';
import Cardiology from '@assets/images/specialties/cardiologia.svg';
import Dermatology from '@assets/images/specialties/dermatologia.svg';
import Endocrinology from '@assets/images/specialties/endocrinologia.svg';
import Gynecology from '@assets/images/specialties/ginecologia.svg';

// 单独维护SVG组件映射表
const SvgComponents: IObjectKeys = {
  Alergología: Alergology,
  Cardiología: Cardiology,
  Dermatología: Dermatology,
  Endocrinología: Endocrinology,
  Ginecología: Gynecology,
};

// 处理数据时无需添加img字段,直接保留原数据结构
export const addingImgToSpecialties = (specialties: Speciality[]) =>
  specialties.map((specialty) => ({
    ...specialty,
  }));
  1. 渲染时根据专业名称匹配SVG组件
// 在渲染组件中引入映射表
import { SvgComponents } from './your-file-path';

const SpecialtyItem = ({ specialty }: { specialty: Speciality }) => {
  // 根据专业名称获取对应的SVG组件
  const SvgIcon = SvgComponents[specialty.name];
  
  return (
    <View>
      <Text>{specialty.name}</Text>
      {/* 渲染SVG组件,可自定义宽高 */}
      {SvgIcon && <SvgIcon width={24} height={24} />}
    </View>
  );
};

方案2:动态加载SVG路径(适合远程或需动态切换场景)

如果必须在数据中关联SVG信息,可存储SVG文件的本地路径,使用react-native-svg的SvgUri组件动态加载:

// 处理数据时存储SVG路径
export const addingImgToSpecialties = (specialties: Speciality[]) =>
  specialties.map((specialty) => {
    const svgPathMap = {
      Alergología: require('@assets/images/specialties/alergologia.svg').uri,
      Cardiología: require('@assets/images/specialties/cardiologia.svg').uri,
      // 其他专业路径...
    };
    return {
      ...specialty,
      svgUri: svgPathMap[specialty.name],
    };
  });

// 渲染时使用SvgUri
import { SvgUri } from 'react-native-svg';

const SpecialtyItem = ({ specialty }: { specialty: Speciality }) => (
  <View>
    <Text>{specialty.name}</Text>
    <SvgUri uri={specialty.svgUri} width={24} height={24} />
  </View>
);

内容的提问来源于stack exchange,提问作者Daniela Avendaño

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 09:39:22