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组件。
- 单独维护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, }));
- 渲染时根据专业名称匹配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
相关产品推荐
相关产品推荐

