React应用中structuredClone函数Windows下报DataCloneError求助
解决structuredClone无法克隆React元素的DataCloneError问题
报错原因
你遇到的DataCloneError: 无法在'Window'上执行'structuredClone':Symbol(react.element)无法被克隆,本质是要克隆的对象中包含React元素——React元素内部带有Symbol(react.element)标识,而structuredClone不支持克隆Symbol类型以及带有React内部标识的对象。
跨系统(Ubuntu正常/Windows报错)的差异,大概率是Windows环境下的业务逻辑中,reslgs、travellerData或travandSeat里意外混入了React元素(比如组件实例、JSX片段),而Ubuntu环境下这些变量是纯数据对象,因此没有触发报错。
针对你尝试方法的分析
- 直接调用
structuredClone:无效,因为对象里的React元素无法被序列化 JSON.parse(JSON.stringify()):会丢失Symbol、函数、undefined等数据,若存在循环引用还会直接报错,不是可靠方案structuredClone(toRaw(...)):toRaw多是Vue生态的API,在React中不生效,且核心问题(React元素未剥离)没解决
可行解决方案
方案1:手动剥离React元素,只克隆纯数据
在克隆前,检查并提取对象中的纯数据字段,排除React元素或组件实例:
// 示例:假设travellerData包含React元素,仅保留需要的纯数据 const cleanTraveller = { name: travellerData.name, age: travellerData.age, // 只保留业务数据,剔除JSX、组件实例等非序列化内容 }; const cleanSeatData = { seatId: travandSeat.seatId, row: travandSeat.row // 同样处理seatData中的纯数据 }; flightnewDatas.push(structuredClone({ ...reslgs, traveller: cleanTraveller, seatData: cleanSeatData, seatArray: reslgs?.seatArray || [], noOfSeatsSelected: 0 }));
方案2:自定义深克隆函数,处理React元素
写一个递归克隆函数,遇到React元素时按需处理(跳过或提取props数据):
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; // 判断是否为React元素(通过React内部的Symbol标识) if (obj.$$typeof === Symbol.for('react.element')) { // 可选:返回null,或提取元素的props数据,根据业务需求调整 return { type: obj.type, props: deepClone(obj.props), key: obj.key }; } if (Array.isArray(obj)) { return obj.map(item => deepClone(item)); } const clonedObj = {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { clonedObj[key] = deepClone(obj[key]); } } return clonedObj; } // 使用自定义克隆函数 flightnewDatas.push(deepClone({ ...reslgs, traveller: travellerData, seatData: travandSeat, seatArray: reslgs?.seatArray || [], noOfSeatsSelected: 0 }));
方案3:使用lodash.cloneDeep(需自定义处理逻辑)
如果项目已引入lodash,可使用cloneDeep并配置自定义克隆器处理React元素:
import cloneDeep from 'lodash/cloneDeep'; const customClone = (value) => { if (value?.$$typeof === Symbol.for('react.element')) { // 按需处理:比如仅保留props数据 return value.props; } }; const clonedData = cloneDeep( { ...reslgs, traveller: travellerData, seatData: travandSeat, seatArray: reslgs?.seatArray || [], noOfSeatsSelected: 0 }, customClone ); flightnewDatas.push(clonedData);
额外排查建议
分别在Ubuntu和Windows环境下打印reslgs、travellerData、travandSeat的结构,确认Windows环境中哪个变量混入了React元素,从源头避免非数据内容进入克隆流程。
内容的提问来源于stack exchange,提问作者Pooja Thathera
相关产品推荐
相关产品推荐

