React Native中API返回JSON对象与本地同内容对象比较返回false问题
问题说明
需要对比API返回的对象与本地定义对象的相等性,控制台打印的两个对象可见内容完全一致,但比较结果始终为false,需要明确原因和正确的实现方式。
对应业务代码如下:
const [QuizCategoriesData, setQuizCategoriesData] = useState([]) const getData = async () => { const url = `https://eu-central-1.aws.data.mongodb-api.com/app/application-0-ekvws/endpoint/zdalneAPIHurraFajnie?secret=sekret&arg1=Expert_1`; const res = await fetch(url); const data = await res.json(); const filterCategory = data.filter(item=> item.category === 'Mentalność bogacenia się') setQuizCategoriesData(filterCategory[0].data) }; useEffect(() => { getData(); }, []); const APIObject = QuizCategoriesData; let arr2 = [{ "correct_option": "Jupiter", "difficulty": "easy", "options": ["Jupiter", "Saturn", "Neptune", "Mercury"], "question": "What’s the biggest planet in our solar system?" }]; console.log('api', APIObject[0]) console.log('local', arr2[0]) console.log('Comprasion:',JSON.stringify(APIObject[0]) === JSON.stringify(arr2[0])) // 控制台返回false
核心原因
- JavaScript中对象属于引用类型,直接使用
===比较时,本质对比的是两个对象的内存引用地址,而非实际存储的内容。哪怕两个对象属性、值完全一致,只要是独立创建的不同实例,直接比较都会返回false。 - 即使使用
JSON.stringify()序列化后转字符串对比,也会因为存在控制台不可见的差异返回false,常见的隐藏差异包括:- 两个对象的属性排列顺序不一致
- API返回的对象存在控制台未打印的不可枚举属性、隐藏字段
- 属性值存在类型差异,比如API返回的数字
1和本地定义的字符串"1",控制台打印视觉效果完全一致,但实际类型不同 - 字符串属性中包含不可见特殊字符,比如零宽空格、多余换行符、重音字符编码差异
- 属性值存在
undefined、Symbol等无法被JSON正常序列化的内容
- 额外注意:React的state更新是异步的,组件首次渲染时
QuizCategoriesData还是初始空数组,此时取APIObject[0]会得到undefined,也会导致对比结果不符合预期。
可行解决方案
- 优先使用成熟的深度对比能力判断对象内容一致性,无需手动排查隐藏差异,即可准确得到两个对象的内容对比结果,也支持定位具体存在差异的字段。
- 可以自行实现简易的深度相等判断函数,参考实现:
function isDeepEqual(obj1, obj2) { // 基础类型直接判断值是否相等 if (obj1 === obj2) return true // 类型不匹配、空值场景直接返回false if (typeof obj1 !== 'object' || typeof obj2 !== 'object' || obj1 === null || obj2 === null) return false // 对比属性数量 const keys1 = Object.keys(obj1) const keys2 = Object.keys(obj2) if (keys1.length !== keys2.length) return false // 递归对比每一个属性 for (const key of keys1) { if (!keys2.includes(key) || !isDeepEqual(obj1[key], obj2[key])) return false } return true }
- 如果需要定位
JSON.stringify对比失败的具体原因,可以直接打印两个对象序列化后的完整字符串逐字比对,或者遍历所有属性逐一打印值和类型,即可找到隐藏的差异点。
内容的提问来源于stack exchange,提问作者Viniste
相关产品推荐
相关产品推荐

